File:
[local] /
rpl /
src /
transliteration.c
Revision
1.31:
download - view:
text,
annotated -
select for diffs -
revision graph
Tue Jun 21 15:26:36 2011 UTC (13 years, 10 months ago) by
bertrand
Branches:
MAIN
CVS tags:
HEAD
Correction d'une réinitialisation sauvage de la pile des variables par niveau
dans la copie de la structure de description du processus. Cela corrige
la fonction SPAWN qui échouait sur un segmentation fault car la pile des
variables par niveau était vide alors même que l'arbre des variables contenait
bien les variables. Passage à la prerelease 2.
1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.0.prerelease.2
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
CVSweb interface <joel.bertrand@systella.fr>