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