1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.3
4: Copyright (C) 1989-2011 Dr. BERTRAND Joël
5:
6: This file is part of RPL/2.
7:
8: RPL/2 is free software; you can redistribute it and/or modify it
9: under the terms of the CeCILL V2 License as published by the french
10: CEA, CNRS and INRIA.
11:
12: RPL/2 is distributed in the hope that it will be useful, but WITHOUT
13: ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14: FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License
15: for more details.
16:
17: You should have received a copy of the CeCILL License
18: along with RPL/2. If not, write to info@cecill.info.
19: ================================================================================
20: */
21:
22:
23: #include "rpl-conv.h"
24: #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 = 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: long i;
179: long nombre_arguments;
180:
181: pid_t pid;
182:
183: sigset_t oldset;
184: sigset_t set;
185:
186: struct sigaction action_passee;
187:
188: unsigned char *tampon;
189:
190: unsigned long longueur_lecture;
191: unsigned long nombre_iterations;
192: unsigned long pointeur;
193:
194: if ((arguments = malloc(3 * sizeof(char **))) == NULL)
195: {
196: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
197: return;
198: }
199:
200: if ((arguments[0] = malloc((strlen("locale") + 1) * sizeof(char))) == NULL)
201: {
202: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
203: return;
204: }
205:
206: if ((arguments[1] = malloc((strlen("charmap") + 1) * sizeof(char))) == NULL)
207: {
208: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
209: return;
210: }
211:
212: strcpy(arguments[0], "locale");
213: strcpy(arguments[1], "charmap");
214: arguments[2] = NULL;
215:
216: nombre_arguments = 2;
217:
218: if (pipe(pipes_entree) != 0)
219: {
220: (*s_etat_processus).erreur_systeme = d_es_processus;
221: return;
222: }
223:
224: if (pipe(pipes_sortie) != 0)
225: {
226: (*s_etat_processus).erreur_systeme = d_es_processus;
227: return;
228: }
229:
230: if (pipe(pipes_erreur) != 0)
231: {
232: (*s_etat_processus).erreur_systeme = d_es_processus;
233: return;
234: }
235:
236: sigfillset(&set);
237: pthread_sigmask(SIG_BLOCK, &set, &oldset);
238:
239: verrouillage_threads_concurrents(s_etat_processus);
240: pid = fork();
241: deverrouillage_threads_concurrents(s_etat_processus);
242:
243: pthread_sigmask(SIG_SETMASK, &oldset, NULL);
244: sigpending(&set);
245:
246: if (pid < 0)
247: {
248: if (close(pipes_entree[0]) != 0)
249: {
250: (*s_etat_processus).erreur_systeme = d_es_processus;
251: return;
252: }
253:
254: if (close(pipes_entree[1]) != 0)
255: {
256: (*s_etat_processus).erreur_systeme = d_es_processus;
257: return;
258: }
259:
260: if (close(pipes_sortie[0]) != 0)
261: {
262: (*s_etat_processus).erreur_systeme = d_es_processus;
263: return;
264: }
265:
266: if (close(pipes_sortie[1]) != 0)
267: {
268: (*s_etat_processus).erreur_systeme = d_es_processus;
269: return;
270: }
271:
272: if (close(pipes_erreur[0]) != 0)
273: {
274: (*s_etat_processus).erreur_systeme = d_es_processus;
275: return;
276: }
277:
278: if (close(pipes_erreur[1]) != 0)
279: {
280: (*s_etat_processus).erreur_systeme = d_es_processus;
281: return;
282: }
283:
284: (*s_etat_processus).erreur_systeme = d_es_processus;
285: return;
286: }
287: else if (pid == 0)
288: {
289: if (close(pipes_entree[1]) != 0)
290: {
291: (*s_etat_processus).erreur_systeme = d_es_processus;
292: return;
293: }
294:
295: if (close(pipes_sortie[0]) != 0)
296: {
297: (*s_etat_processus).erreur_systeme = d_es_processus;
298: return;
299: }
300:
301: if (close(pipes_erreur[0]) != 0)
302: {
303: (*s_etat_processus).erreur_systeme = d_es_processus;
304: return;
305: }
306:
307: if (pipes_entree[0] != STDIN_FILENO)
308: {
309: if (dup2(pipes_entree[0], STDIN_FILENO) == -1)
310: {
311: (*s_etat_processus).erreur_systeme = d_es_processus;
312: return;
313: }
314: }
315:
316: if (pipes_sortie[1] != STDOUT_FILENO)
317: {
318: if (dup2(pipes_sortie[1], STDOUT_FILENO) == -1)
319: {
320: (*s_etat_processus).erreur_systeme = d_es_processus;
321: return;
322: }
323: }
324:
325: if (pipes_sortie[1] != STDERR_FILENO)
326: {
327: if (dup2(pipes_sortie[1], STDERR_FILENO) == -1)
328: {
329: (*s_etat_processus).erreur_systeme = d_es_processus;
330: return;
331: }
332: }
333:
334: if (nombre_arguments != 0)
335: {
336: execvp(arguments[0], arguments);
337: }
338: else
339: {
340: exit(EXIT_SUCCESS);
341: }
342:
343: /*
344: * L'appel système execvp() a généré une erreur et n'a pu exécuter
345: * argument[0] (fichier non exécutable ou inexistant).
346: */
347:
348: close(pipes_entree[0]);
349: close(pipes_sortie[1]);
350:
351: for(i = 0; i < nombre_arguments; i++)
352: {
353: free(arguments[i]);
354: }
355:
356: free(arguments);
357: (*s_etat_processus).erreur_systeme = d_es_processus;
358:
359: /*
360: * Envoi d'une erreur dans le pipe idoine. On ne regarde pas
361: * le nombre d'octets écrits car l'erreur ne pourra de toute
362: * façon pas être traitée.
363: */
364:
365: write_atomic(s_etat_processus, pipes_erreur[1], " ", 1);
366: close(pipes_erreur[1]);
367:
368: exit(EXIT_SUCCESS);
369: }
370: else
371: {
372: if (close(pipes_entree[0]) != 0)
373: {
374: (*s_etat_processus).erreur_systeme = d_es_processus;
375: return;
376: }
377:
378: if (close(pipes_sortie[1]) != 0)
379: {
380: (*s_etat_processus).erreur_systeme = d_es_processus;
381: return;
382: }
383:
384: if (close(pipes_erreur[1]) != 0)
385: {
386: (*s_etat_processus).erreur_systeme = d_es_processus;
387: return;
388: }
389:
390: if (close(pipes_entree[1]) != 0)
391: {
392: (*s_etat_processus).erreur_systeme = d_es_processus;
393: return;
394: }
395:
396: do
397: {
398: if (kill(pid, 0) != 0)
399: {
400: break;
401: }
402:
403: /*
404: * Récupération de la valeur de retour du processus détaché
405: */
406:
407: # ifndef SEMAPHORES_NOMMES
408: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
409: # else
410: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
411: # endif
412: {
413: (*s_etat_processus).erreur_systeme = d_es_processus;
414: return;
415: }
416:
417: if (waitpid(pid, &status, 0) == -1)
418: {
419: # ifndef SEMAPHORES_NOMMES
420: if (sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
421: # else
422: if (sem_wait((*s_etat_processus).semaphore_fork) == -1)
423: # endif
424: {
425: if (errno != EINTR)
426: {
427: (*s_etat_processus).erreur_systeme = d_es_processus;
428: return;
429: }
430: }
431:
432: (*s_etat_processus).erreur_systeme = d_es_processus;
433: return;
434: }
435:
436: # ifndef SEMAPHORES_NOMMES
437: if (sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
438: # else
439: if (sem_wait((*s_etat_processus).semaphore_fork) == -1)
440: # endif
441: {
442: if (errno != EINTR)
443: {
444: (*s_etat_processus).erreur_systeme = d_es_processus;
445: return;
446: }
447: }
448: } while((!WIFEXITED(status)) && (!WIFSIGNALED(status)));
449:
450: longueur_lecture = 256;
451: pointeur = 0;
452: nombre_iterations = 1;
453:
454: if ((tampon = malloc((longueur_lecture + 1) *
455: sizeof(unsigned char))) == NULL)
456: {
457: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
458: return;
459: }
460:
461: tampon[0] = d_code_fin_chaine;
462:
463: # ifndef SEMAPHORES_NOMMES
464: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
465: # else
466: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
467: # endif
468: {
469: (*s_etat_processus).erreur_systeme = d_es_processus;
470: return;
471: }
472:
473: while((ios = read_atomic(s_etat_processus,
474: pipes_sortie[0], &(tampon[pointeur]),
475: longueur_lecture)) > 0)
476: {
477: # ifndef SEMAPHORES_NOMMES
478: while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
479: # else
480: while(sem_wait((*s_etat_processus).semaphore_fork) == -1)
481: # endif
482: {
483: if (errno != EINTR)
484: {
485: (*s_etat_processus).erreur_systeme = d_es_processus;
486: return;
487: }
488: }
489:
490: tampon[pointeur + ios] = d_code_fin_chaine;
491: pointeur += longueur_lecture;
492: nombre_iterations++;
493:
494: if ((tampon = realloc(tampon,
495: ((nombre_iterations * longueur_lecture) + 1) *
496: sizeof(unsigned char))) == NULL)
497: {
498: (*s_etat_processus).erreur_systeme =
499: d_es_allocation_memoire;
500: return;
501: }
502:
503: # ifndef SEMAPHORES_NOMMES
504: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
505: # else
506: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
507: # endif
508: {
509: (*s_etat_processus).erreur_systeme = d_es_processus;
510: return;
511: }
512: }
513:
514: # ifndef SEMAPHORES_NOMMES
515: while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
516: # else
517: while(sem_wait((*s_etat_processus).semaphore_fork) == -1)
518: # endif
519: {
520: if (errno != EINTR)
521: {
522: (*s_etat_processus).erreur_systeme = d_es_processus;
523: return;
524: }
525: }
526:
527: if (strlen(tampon) == 0)
528: {
529: (*s_etat_processus).erreur_systeme = d_es_processus;
530: return;
531: }
532:
533: tampon[strlen(tampon) - 1] = d_code_fin_chaine;
534:
535: if (ios == -1)
536: {
537: (*s_etat_processus).erreur_systeme = d_es_processus;
538: return;
539: }
540:
541: if (close(pipes_sortie[0]) != 0)
542: {
543: (*s_etat_processus).erreur_systeme = d_es_processus;
544: return;
545: }
546:
547: if (strlen(tampon) > 0)
548: {
549: (*s_etat_processus).localisation = tampon;
550: }
551: else
552: {
553: free(tampon);
554:
555: if (((*s_etat_processus).localisation = malloc((strlen(d_locale)
556: + 1) * sizeof(unsigned char))) == NULL)
557: {
558: (*s_etat_processus).erreur_systeme = d_es_processus;
559: return;
560: }
561:
562: strcpy((*s_etat_processus).localisation, d_locale);
563: }
564:
565: if (sigaction(SIGINT, &action_passee, NULL) != 0)
566: {
567: for(i = 0; i < nombre_arguments; i++)
568: {
569: free(arguments[i]);
570: }
571:
572: free(arguments);
573: (*s_etat_processus).erreur_systeme = d_es_signal;
574: return;
575: }
576:
577: for(i = 0; i < nombre_arguments; i++)
578: {
579: free(arguments[i]);
580: }
581:
582: free(arguments);
583:
584: # ifndef SEMAPHORES_NOMMES
585: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
586: # else
587: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
588: # endif
589: {
590: (*s_etat_processus).erreur_systeme = d_es_processus;
591: return;
592: }
593:
594: if (read_atomic(s_etat_processus, pipes_erreur[0], tampon, 1) > 0)
595: {
596: // Le processus fils renvoie une erreur.
597:
598: free(tampon);
599:
600: if (((*s_etat_processus).localisation = malloc((strlen(d_locale)
601: + 1) * sizeof(unsigned char))) == NULL)
602: {
603: (*s_etat_processus).erreur_systeme = d_es_processus;
604: return;
605: }
606:
607: strcpy((*s_etat_processus).localisation, d_locale);
608: }
609:
610: # ifndef SEMAPHORES_NOMMES
611: while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
612: # else
613: while(sem_wait((*s_etat_processus).semaphore_fork) == -1)
614: # endif
615: {
616: if (errno != EINTR)
617: {
618: (*s_etat_processus).erreur_systeme = d_es_processus;
619: return;
620: }
621: }
622:
623: if (close(pipes_erreur[0]) != 0)
624: {
625: (*s_etat_processus).erreur_systeme = d_es_processus;
626: return;
627: }
628: }
629:
630: return;
631: }
632:
633:
634: int
635: transliterated_fprintf(struct_processus *s_etat_processus, file *flux,
636: const char *format, ...)
637: {
638: int ios;
639:
640: unsigned char *tampon;
641: unsigned char *tampon2;
642:
643: va_list arguments;
644:
645: va_start(arguments, format);
646:
647: # ifdef OS2
648: unsigned char *ptr_e;;
649: unsigned char *ptr_l;;
650: unsigned char *tampon3;
651:
652: unsigned long i;
653: # endif
654:
655: if (valsprintf(&tampon, format, arguments) < 0)
656: {
657: va_end(arguments);
658:
659: if (s_etat_processus != NULL)
660: {
661: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
662: }
663:
664: return(-1);
665: }
666:
667: va_end(arguments);
668:
669: if (s_etat_processus != NULL)
670: {
671: if ((tampon2 = transliteration(s_etat_processus, tampon,
672: d_locale, (*s_etat_processus).localisation)) == NULL)
673: {
674: free(tampon);
675: return(-1);
676: }
677:
678: free(tampon);
679: }
680: else
681: {
682: tampon2 = tampon;
683: }
684:
685: # ifdef OS2
686: if ((flux == stdin) || (flux == stdout))
687: {
688: i = 0;
689: ptr_l = tampon2;
690:
691: while((*ptr_l) != d_code_fin_chaine)
692: {
693: if ((*ptr_l) == '\n')
694: {
695: i++;
696: }
697:
698: ptr_l++;
699: }
700:
701: if ((tampon3 = malloc((strlen(tampon2) + i + 1) *
702: sizeof(unsigned char))) == NULL)
703: {
704: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
705: return(NULL);
706: }
707:
708: ptr_e = tampon3;
709: ptr_l = tampon2;
710:
711: while((*ptr_l) != d_code_fin_chaine)
712: {
713: (*ptr_e) = (*ptr_l);
714:
715: if ((*ptr_l) == '\n')
716: {
717: (*(++ptr_e)) = '\r';
718: ptr_e++;
719: ptr_l++;
720: }
721: else
722: {
723: ptr_e++;
724: ptr_l++;
725: }
726: }
727:
728: (*ptr_e) = d_code_fin_chaine;
729:
730: free(tampon2);
731: tampon2 = tampon3;
732: }
733: # endif
734:
735: # ifdef SunOS
736: while((ios = fprintf(flux, "%s", tampon2)) < 0)
737: {
738: if ((errno != EINTR) && (errno != 0))
739: {
740: break;
741: }
742: }
743: # else
744: ios = fprintf(flux, "%s", tampon2);
745: # endif
746:
747: free(tampon2);
748:
749: return(ios);
750: }
751:
752:
753: int
754: tex_fprintf(struct_processus *s_etat_processus,
755: file *flux, const char *format, ...)
756: {
757: int ios;
758:
759: unsigned char *tampon;
760: unsigned char *tampon2;
761:
762: va_list arguments;
763:
764: va_start(arguments, format);
765:
766: if (valsprintf(&tampon, format, arguments) < 0)
767: {
768: va_end(arguments);
769:
770: if (s_etat_processus != NULL)
771: {
772: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
773: }
774:
775: return(-1);
776: }
777:
778: va_end(arguments);
779:
780: if ((tampon2 = transliteration(s_etat_processus, tampon,
781: d_locale, ds_tex_encodage_3)) == NULL)
782: {
783: free(tampon);
784: return(-1);
785: }
786:
787: free(tampon);
788:
789: # ifdef SunOS
790: while((ios = fprintf(flux, "%s", tampon2)) < 0)
791: {
792: if ((errno != EINTR) && (errno != 0))
793: {
794: break;
795: }
796: }
797: # else
798: ios = fprintf(flux, "%s", tampon2);
799: # endif
800:
801: free(tampon2);
802:
803: return(ios);
804: }
805:
806: #undef readline
807:
808: unsigned char *
809: readline_wrapper(unsigned char *invite)
810: {
811: unsigned char *chaine;
812:
813: chaine = readline(invite);
814: printf("\r");
815:
816: return(chaine);
817: }
818:
819:
820: #define fprintf NULL
821: #define printf NULL
822:
823: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>