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