![]() ![]() | ![]() |
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: #include "tex-conv.h" 25: 26: #include <stdarg.h> 27: 28: #undef fprintf 29: #undef printf 30: 31: 32: /* 33: ================================================================================ 34: Fonction de translitération 35: ================================================================================ 36: Entrées : 37: -------------------------------------------------------------------------------- 38: Sorties : 39: -------------------------------------------------------------------------------- 40: Effets de bord : néant 41: ================================================================================ 42: */ 43: 44: unsigned char * 45: transliteration(struct_processus *s_etat_processus, 46: unsigned char *chaine_entree, 47: unsigned char *codage_entree, 48: unsigned char *codage_sortie) 49: { 50: unsigned char *codage_sortie_transliteral; 51: unsigned char *tampon; 52: 53: if ((codage_sortie_transliteral = malloc((strlen(codage_sortie) 54: + strlen("//TRANSLIT") + 1) * sizeof(unsigned char))) == NULL) 55: { 56: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 57: return(NULL); 58: } 59: 60: sprintf(codage_sortie_transliteral, "%s//TRANSLIT", codage_sortie); 61: 62: tampon = reencodage(s_etat_processus, chaine_entree, 63: codage_entree, codage_sortie_transliteral); 64: free(codage_sortie_transliteral); 65: 66: return(tampon); 67: } 68: 69: 70: unsigned char * 71: reencodage(struct_processus *s_etat_processus, 72: unsigned char *chaine_entree, 73: unsigned char *codage_entree, 74: unsigned char *codage_sortie) 75: { 76: # define d_LONGUEUR 1024 77: 78: iconv_t transcodage; 79: 80: size_t ios; 81: size_t longueur_entree; 82: size_t longueur_sortie; 83: 84: unsigned char *buffer_entree; 85: unsigned char *buffer_sortie; 86: unsigned char *chaine_sortie; 87: unsigned char *pointeur; 88: unsigned char *tampon; 89: 90: if ((transcodage = iconv_open(codage_sortie, codage_entree)) == 91: (iconv_t) -1) 92: { 93: (*s_etat_processus).erreur_execution = d_ex_erreur_transcodage; 94: return(NULL); 95: } 96: 97: buffer_entree = chaine_entree; 98: longueur_entree = strlen(chaine_entree); 99: 100: if ((chaine_sortie = malloc(sizeof(unsigned char))) == NULL) 101: { 102: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 103: return(NULL); 104: } 105: 106: chaine_sortie[0] = d_code_fin_chaine; 107: 108: if ((buffer_sortie = malloc((d_LONGUEUR + 1) * sizeof(char))) == NULL) 109: { 110: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 111: return(NULL); 112: } 113: 114: do 115: { 116: longueur_sortie = d_LONGUEUR; 117: pointeur = buffer_sortie; 118: 119: if ((ios = iconv(transcodage, (char **) &buffer_entree, 120: &longueur_entree, (char **) &pointeur, &longueur_sortie)) 121: == (size_t) -1) 122: { 123: // On autorise les erreurs EINVAL et EILSEQ 124: if (errno == EILSEQ) 125: { 126: free(buffer_sortie); 127: free(chaine_sortie); 128: 129: (*s_etat_processus).erreur_execution = d_ex_erreur_transcodage; 130: return(NULL); 131: } 132: } 133: 134: tampon = (unsigned char *) chaine_sortie; 135: (*pointeur) = d_code_fin_chaine; 136: 137: if ((chaine_sortie = malloc((strlen(tampon) + strlen(buffer_sortie) + 1) 138: * sizeof(unsigned char))) == NULL) 139: { 140: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 141: return(NULL); 142: } 143: 144: sprintf(chaine_sortie, "%s%s", tampon, buffer_sortie); 145: free(tampon); 146: } while((*buffer_entree) != d_code_fin_chaine); 147: 148: free(buffer_sortie); 149: iconv_close(transcodage); 150: 151: return(chaine_sortie); 152: } 153: 154: 155: /* 156: ================================================================================ 157: Fonctions spécifiques 158: ================================================================================ 159: Entrées : 160: -------------------------------------------------------------------------------- 161: Sorties : 162: -------------------------------------------------------------------------------- 163: Effets de bord : néant 164: ================================================================================ 165: */ 166: 167: void 168: localisation_courante(struct_processus *s_etat_processus) 169: { 170: char **arguments; 171: 172: int ios; 173: int pipes_entree[2]; 174: int pipes_erreur[2]; 175: int pipes_sortie[2]; 176: int status; 177: 178: logical1 drapeau_fin; 179: 180: long i; 181: long nombre_arguments; 182: 183: pid_t pid; 184: 185: sigset_t oldset; 186: sigset_t set; 187: 188: struct sigaction action_passee; 189: 190: unsigned char *tampon; 191: 192: unsigned long longueur_lecture; 193: unsigned long nombre_iterations; 194: unsigned long pointeur; 195: 196: if ((arguments = malloc(3 * sizeof(char **))) == NULL) 197: { 198: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 199: return; 200: } 201: 202: if ((arguments[0] = malloc((strlen("locale") + 1) * sizeof(char))) == NULL) 203: { 204: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 205: return; 206: } 207: 208: if ((arguments[1] = malloc((strlen("charmap") + 1) * sizeof(char))) == NULL) 209: { 210: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 211: return; 212: } 213: 214: strcpy(arguments[0], "locale"); 215: strcpy(arguments[1], "charmap"); 216: arguments[2] = NULL; 217: 218: nombre_arguments = 2; 219: drapeau_fin = d_faux; 220: 221: if (pipe(pipes_entree) != 0) 222: { 223: (*s_etat_processus).erreur_systeme = d_es_processus; 224: return; 225: } 226: 227: if (pipe(pipes_sortie) != 0) 228: { 229: (*s_etat_processus).erreur_systeme = d_es_processus; 230: return; 231: } 232: 233: if (pipe(pipes_erreur) != 0) 234: { 235: (*s_etat_processus).erreur_systeme = d_es_processus; 236: return; 237: } 238: 239: sigfillset(&set); 240: pthread_sigmask(SIG_BLOCK, &set, &oldset); 241: 242: verrouillage_threads_concurrents(s_etat_processus); 243: pid = fork(); 244: deverrouillage_threads_concurrents(s_etat_processus); 245: 246: pthread_sigmask(SIG_SETMASK, &oldset, NULL); 247: sigpending(&set); 248: 249: if (pid < 0) 250: { 251: if (close(pipes_entree[0]) != 0) 252: { 253: (*s_etat_processus).erreur_systeme = d_es_processus; 254: return; 255: } 256: 257: if (close(pipes_entree[1]) != 0) 258: { 259: (*s_etat_processus).erreur_systeme = d_es_processus; 260: return; 261: } 262: 263: if (close(pipes_sortie[0]) != 0) 264: { 265: (*s_etat_processus).erreur_systeme = d_es_processus; 266: return; 267: } 268: 269: if (close(pipes_sortie[1]) != 0) 270: { 271: (*s_etat_processus).erreur_systeme = d_es_processus; 272: return; 273: } 274: 275: if (close(pipes_erreur[0]) != 0) 276: { 277: (*s_etat_processus).erreur_systeme = d_es_processus; 278: return; 279: } 280: 281: if (close(pipes_erreur[1]) != 0) 282: { 283: (*s_etat_processus).erreur_systeme = d_es_processus; 284: return; 285: } 286: 287: (*s_etat_processus).erreur_systeme = d_es_processus; 288: return; 289: } 290: else if (pid == 0) 291: { 292: if (close(pipes_entree[1]) != 0) 293: { 294: (*s_etat_processus).erreur_systeme = d_es_processus; 295: return; 296: } 297: 298: if (close(pipes_sortie[0]) != 0) 299: { 300: (*s_etat_processus).erreur_systeme = d_es_processus; 301: return; 302: } 303: 304: if (close(pipes_erreur[0]) != 0) 305: { 306: (*s_etat_processus).erreur_systeme = d_es_processus; 307: return; 308: } 309: 310: if (pipes_entree[0] != STDIN_FILENO) 311: { 312: if (dup2(pipes_entree[0], STDIN_FILENO) == -1) 313: { 314: (*s_etat_processus).erreur_systeme = d_es_processus; 315: return; 316: } 317: } 318: 319: if (pipes_sortie[1] != STDOUT_FILENO) 320: { 321: if (dup2(pipes_sortie[1], STDOUT_FILENO) == -1) 322: { 323: (*s_etat_processus).erreur_systeme = d_es_processus; 324: return; 325: } 326: } 327: 328: if (pipes_sortie[1] != STDERR_FILENO) 329: { 330: if (dup2(pipes_sortie[1], STDERR_FILENO) == -1) 331: { 332: (*s_etat_processus).erreur_systeme = d_es_processus; 333: return; 334: } 335: } 336: 337: if (nombre_arguments != 0) 338: { 339: execvp(arguments[0], arguments); 340: } 341: else 342: { 343: exit(EXIT_SUCCESS); 344: } 345: 346: /* 347: * L'appel système execvp() a généré une erreur et n'a pu exécuter 348: * argument[0] (fichier non exécutable ou inexistant). 349: */ 350: 351: close(pipes_entree[0]); 352: close(pipes_sortie[1]); 353: 354: for(i = 0; i < nombre_arguments; i++) 355: { 356: free(arguments[i]); 357: } 358: 359: free(arguments); 360: (*s_etat_processus).erreur_systeme = d_es_processus; 361: 362: /* 363: * Envoi d'une erreur dans le pipe idoine. On ne regarde pas 364: * le nombre d'octets écrits car l'erreur ne pourra de toute 365: * façon pas être traitée. 366: */ 367: 368: write_atomic(s_etat_processus, pipes_erreur[1], " ", 1); 369: close(pipes_erreur[1]); 370: 371: exit(EXIT_SUCCESS); 372: } 373: else 374: { 375: if (close(pipes_entree[0]) != 0) 376: { 377: (*s_etat_processus).erreur_systeme = d_es_processus; 378: return; 379: } 380: 381: if (close(pipes_sortie[1]) != 0) 382: { 383: (*s_etat_processus).erreur_systeme = d_es_processus; 384: return; 385: } 386: 387: if (close(pipes_erreur[1]) != 0) 388: { 389: (*s_etat_processus).erreur_systeme = d_es_processus; 390: return; 391: } 392: 393: if (close(pipes_entree[1]) != 0) 394: { 395: (*s_etat_processus).erreur_systeme = d_es_processus; 396: return; 397: } 398: 399: do 400: { 401: if (kill(pid, 0) != 0) 402: { 403: break; 404: } 405: 406: /* 407: * Récupération de la valeur de retour du processus détaché 408: */ 409: 410: # ifndef SEMAPHORES_NOMMES 411: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) 412: # else 413: if (sem_post((*s_etat_processus).semaphore_fork) != 0) 414: # endif 415: { 416: (*s_etat_processus).erreur_systeme = d_es_processus; 417: return; 418: } 419: 420: if (waitpid(pid, &status, 0) == -1) 421: { 422: # ifndef SEMAPHORES_NOMMES 423: if (sem_wait(&((*s_etat_processus).semaphore_fork)) == -1) 424: # else 425: if (sem_wait((*s_etat_processus).semaphore_fork) == -1) 426: # endif 427: { 428: if (errno != EINTR) 429: { 430: (*s_etat_processus).erreur_systeme = d_es_processus; 431: return; 432: } 433: } 434: 435: (*s_etat_processus).erreur_systeme = d_es_processus; 436: return; 437: } 438: 439: # ifndef SEMAPHORES_NOMMES 440: if (sem_wait(&((*s_etat_processus).semaphore_fork)) == -1) 441: # else 442: if (sem_wait((*s_etat_processus).semaphore_fork) == -1) 443: # endif 444: { 445: if (errno != EINTR) 446: { 447: (*s_etat_processus).erreur_systeme = d_es_processus; 448: return; 449: } 450: } 451: } while((!WIFEXITED(status)) && (!WIFSIGNALED(status))); 452: 453: longueur_lecture = 256; 454: pointeur = 0; 455: nombre_iterations = 1; 456: 457: if ((tampon = malloc((longueur_lecture + 1) * 458: sizeof(unsigned char))) == NULL) 459: { 460: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 461: return; 462: } 463: 464: tampon[0] = d_code_fin_chaine; 465: 466: # ifndef SEMAPHORES_NOMMES 467: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) 468: # else 469: if (sem_post((*s_etat_processus).semaphore_fork) != 0) 470: # endif 471: { 472: (*s_etat_processus).erreur_systeme = d_es_processus; 473: return; 474: } 475: 476: while((ios = read_atomic(s_etat_processus, 477: pipes_sortie[0], &(tampon[pointeur]), 478: longueur_lecture)) > 0) 479: { 480: # ifndef SEMAPHORES_NOMMES 481: while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1) 482: # else 483: while(sem_wait((*s_etat_processus).semaphore_fork) == -1) 484: # endif 485: { 486: if (errno != EINTR) 487: { 488: (*s_etat_processus).erreur_systeme = d_es_processus; 489: return; 490: } 491: } 492: 493: tampon[pointeur + ios] = d_code_fin_chaine; 494: pointeur += longueur_lecture; 495: nombre_iterations++; 496: 497: if ((tampon = realloc(tampon, 498: ((nombre_iterations * longueur_lecture) + 1) * 499: sizeof(unsigned char))) == NULL) 500: { 501: (*s_etat_processus).erreur_systeme = 502: d_es_allocation_memoire; 503: return; 504: } 505: 506: # ifndef SEMAPHORES_NOMMES 507: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) 508: # else 509: if (sem_post((*s_etat_processus).semaphore_fork) != 0) 510: # endif 511: { 512: (*s_etat_processus).erreur_systeme = d_es_processus; 513: return; 514: } 515: } 516: 517: # ifndef SEMAPHORES_NOMMES 518: while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1) 519: # else 520: while(sem_wait((*s_etat_processus).semaphore_fork) == -1) 521: # endif 522: { 523: if (errno != EINTR) 524: { 525: (*s_etat_processus).erreur_systeme = d_es_processus; 526: return; 527: } 528: } 529: 530: if (strlen(tampon) == 0) 531: { 532: (*s_etat_processus).erreur_systeme = d_es_processus; 533: return; 534: } 535: 536: tampon[strlen(tampon) - 1] = d_code_fin_chaine; 537: 538: if (ios == -1) 539: { 540: (*s_etat_processus).erreur_systeme = d_es_processus; 541: return; 542: } 543: 544: if (close(pipes_sortie[0]) != 0) 545: { 546: (*s_etat_processus).erreur_systeme = d_es_processus; 547: return; 548: } 549: 550: if (strlen(tampon) > 0) 551: { 552: (*s_etat_processus).localisation = tampon; 553: } 554: else 555: { 556: free(tampon); 557: 558: if (((*s_etat_processus).localisation = malloc((strlen(d_locale) 559: + 1) * sizeof(unsigned char))) == NULL) 560: { 561: (*s_etat_processus).erreur_systeme = d_es_processus; 562: return; 563: } 564: 565: strcpy((*s_etat_processus).localisation, d_locale); 566: } 567: 568: if (sigaction(SIGINT, &action_passee, NULL) != 0) 569: { 570: for(i = 0; i < nombre_arguments; i++) 571: { 572: free(arguments[i]); 573: } 574: 575: free(arguments); 576: (*s_etat_processus).erreur_systeme = d_es_signal; 577: return; 578: } 579: 580: for(i = 0; i < nombre_arguments; i++) 581: { 582: free(arguments[i]); 583: } 584: 585: free(arguments); 586: 587: # ifndef SEMAPHORES_NOMMES 588: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0) 589: # else 590: if (sem_post((*s_etat_processus).semaphore_fork) != 0) 591: # endif 592: { 593: (*s_etat_processus).erreur_systeme = d_es_processus; 594: return; 595: } 596: 597: if (read_atomic(s_etat_processus, pipes_erreur[0], tampon, 1) > 0) 598: { 599: // Le processus fils renvoie une erreur. 600: 601: free(tampon); 602: 603: if (((*s_etat_processus).localisation = malloc((strlen(d_locale) 604: + 1) * sizeof(unsigned char))) == NULL) 605: { 606: (*s_etat_processus).erreur_systeme = d_es_processus; 607: return; 608: } 609: 610: strcpy((*s_etat_processus).localisation, d_locale); 611: } 612: 613: # ifndef SEMAPHORES_NOMMES 614: while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1) 615: # else 616: while(sem_wait((*s_etat_processus).semaphore_fork) == -1) 617: # endif 618: { 619: if (errno != EINTR) 620: { 621: (*s_etat_processus).erreur_systeme = d_es_processus; 622: return; 623: } 624: } 625: 626: if (close(pipes_erreur[0]) != 0) 627: { 628: (*s_etat_processus).erreur_systeme = d_es_processus; 629: return; 630: } 631: } 632: 633: return; 634: } 635: 636: 637: int 638: transliterated_fprintf(struct_processus *s_etat_processus, file *flux, 639: const char *format, ...) 640: { 641: int ios; 642: 643: unsigned char *tampon; 644: unsigned char *tampon2; 645: 646: va_list arguments; 647: 648: va_start(arguments, format); 649: 650: # ifdef OS2 651: unsigned char *ptr_e;; 652: unsigned char *ptr_l;; 653: unsigned char *tampon3; 654: 655: unsigned long i; 656: # endif 657: 658: if (valsprintf(&tampon, format, arguments) < 0) 659: { 660: va_end(arguments); 661: 662: if (s_etat_processus != NULL) 663: { 664: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 665: } 666: 667: return(-1); 668: } 669: 670: va_end(arguments); 671: 672: if (s_etat_processus != NULL) 673: { 674: if ((tampon2 = transliteration(s_etat_processus, tampon, 675: d_locale, (*s_etat_processus).localisation)) == NULL) 676: { 677: free(tampon); 678: return(-1); 679: } 680: 681: free(tampon); 682: } 683: else 684: { 685: tampon2 = tampon; 686: } 687: 688: # ifdef OS2 689: if ((flux == stdin) || (flux == stdout)) 690: { 691: i = 0; 692: ptr_l = tampon2; 693: 694: while((*ptr_l) != d_code_fin_chaine) 695: { 696: if ((*ptr_l) == '\n') 697: { 698: i++; 699: } 700: 701: ptr_l++; 702: } 703: 704: if ((tampon3 = malloc((strlen(tampon2) + i + 1) * 705: sizeof(unsigned char))) == NULL) 706: { 707: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 708: return(NULL); 709: } 710: 711: ptr_e = tampon3; 712: ptr_l = tampon2; 713: 714: while((*ptr_l) != d_code_fin_chaine) 715: { 716: (*ptr_e) = (*ptr_l); 717: 718: if ((*ptr_l) == '\n') 719: { 720: (*(++ptr_e)) = '\r'; 721: ptr_e++; 722: ptr_l++; 723: } 724: else 725: { 726: ptr_e++; 727: ptr_l++; 728: } 729: } 730: 731: (*ptr_e) = d_code_fin_chaine; 732: 733: free(tampon2); 734: tampon2 = tampon3; 735: } 736: # endif 737: 738: # ifdef SunOS 739: while((ios = fprintf(flux, "%s", tampon2)) < 0) 740: { 741: if ((errno != EINTR) && (errno != 0)) 742: { 743: break; 744: } 745: } 746: # else 747: ios = fprintf(flux, "%s", tampon2); 748: # endif 749: 750: free(tampon2); 751: 752: return(ios); 753: } 754: 755: 756: int 757: tex_fprintf(struct_processus *s_etat_processus, 758: file *flux, const char *format, ...) 759: { 760: int ios; 761: 762: unsigned char *tampon; 763: unsigned char *tampon2; 764: 765: va_list arguments; 766: 767: va_start(arguments, format); 768: 769: if (valsprintf(&tampon, format, arguments) < 0) 770: { 771: va_end(arguments); 772: 773: if (s_etat_processus != NULL) 774: { 775: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; 776: } 777: 778: return(-1); 779: } 780: 781: va_end(arguments); 782: 783: if ((tampon2 = transliteration(s_etat_processus, tampon, 784: d_locale, ds_tex_encodage_3)) == NULL) 785: { 786: free(tampon); 787: return(-1); 788: } 789: 790: free(tampon); 791: 792: # ifdef SunOS 793: while((ios = fprintf(flux, "%s", tampon2)) < 0) 794: { 795: if ((errno != EINTR) && (errno != 0)) 796: { 797: break; 798: } 799: } 800: # else 801: ios = fprintf(flux, "%s", tampon2); 802: # endif 803: 804: free(tampon2); 805: 806: return(ios); 807: } 808: 809: #undef readline 810: 811: unsigned char * 812: readline_wrapper(unsigned char *invite) 813: { 814: unsigned char *chaine; 815: 816: chaine = readline(invite); 817: printf("\r"); 818: 819: return(chaine); 820: } 821: 822: 823: #define fprintf NULL 824: #define printf NULL 825: 826: // vim: ts=4