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: # ifndef SEMAPHORES_NOMMES
476: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
477: # else
478: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
479: # endif
480: {
481: (*s_etat_processus).erreur_systeme = d_es_processus;
482: return;
483: }
484:
485: while((ios = read_atomic(s_etat_processus,
486: pipes_sortie[0], &(tampon[pointeur]),
487: longueur_lecture)) > 0)
488: {
489: # ifndef SEMAPHORES_NOMMES
490: while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
491: # else
492: while(sem_wait((*s_etat_processus).semaphore_fork) == -1)
493: # endif
494: {
495: if (errno != EINTR)
496: {
497: (*s_etat_processus).erreur_systeme = d_es_processus;
498: return;
499: }
500: }
501:
502: tampon[pointeur + ios] = d_code_fin_chaine;
503: pointeur += longueur_lecture;
504: nombre_iterations++;
505:
506: if ((tampon = realloc(tampon,
507: ((nombre_iterations * longueur_lecture) + 1) *
508: sizeof(unsigned char))) == NULL)
509: {
510: (*s_etat_processus).erreur_systeme =
511: d_es_allocation_memoire;
512: return;
513: }
514:
515: # ifndef SEMAPHORES_NOMMES
516: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
517: # else
518: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
519: # endif
520: {
521: (*s_etat_processus).erreur_systeme = d_es_processus;
522: return;
523: }
524: }
525:
526: # ifndef SEMAPHORES_NOMMES
527: while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
528: # else
529: while(sem_wait((*s_etat_processus).semaphore_fork) == -1)
530: # endif
531: {
532: if (errno != EINTR)
533: {
534: (*s_etat_processus).erreur_systeme = d_es_processus;
535: return;
536: }
537: }
538:
539: if (strlen(tampon) == 0)
540: {
541: (*s_etat_processus).erreur_systeme = d_es_processus;
542: return;
543: }
544:
545: tampon[strlen(tampon) - 1] = d_code_fin_chaine;
546:
547: if (ios == -1)
548: {
549: (*s_etat_processus).erreur_systeme = d_es_processus;
550: return;
551: }
552:
553: if (close(pipes_sortie[0]) != 0)
554: {
555: (*s_etat_processus).erreur_systeme = d_es_processus;
556: return;
557: }
558:
559: if (strlen(tampon) > 0)
560: {
561: (*s_etat_processus).localisation = tampon;
562: }
563: else
564: {
565: free(tampon);
566:
567: if (((*s_etat_processus).localisation = malloc((strlen(d_locale)
568: + 1) * sizeof(unsigned char))) == NULL)
569: {
570: (*s_etat_processus).erreur_systeme = d_es_processus;
571: return;
572: }
573:
574: strcpy((*s_etat_processus).localisation, d_locale);
575: }
576:
577: if (sigaction(SIGINT, &action_passee, NULL) != 0)
578: {
579: for(i = 0; i < nombre_arguments; i++)
580: {
581: free(arguments[i]);
582: }
583:
584: free(arguments);
585: (*s_etat_processus).erreur_systeme = d_es_signal;
586: return;
587: }
588:
589: for(i = 0; i < nombre_arguments; i++)
590: {
591: free(arguments[i]);
592: }
593:
594: free(arguments);
595:
596: # ifndef SEMAPHORES_NOMMES
597: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
598: # else
599: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
600: # endif
601: {
602: (*s_etat_processus).erreur_systeme = d_es_processus;
603: return;
604: }
605:
606: if (read_atomic(s_etat_processus, pipes_erreur[0], tampon, 1) > 0)
607: {
608: // Le processus fils renvoie une erreur.
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: (*s_etat_processus).erreur_execution = d_ex_erreur_processus;
624: return;
625: }
626:
627: # ifndef SEMAPHORES_NOMMES
628: while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
629: # else
630: while(sem_wait((*s_etat_processus).semaphore_fork) == -1)
631: # endif
632: {
633: if (errno != EINTR)
634: {
635: (*s_etat_processus).erreur_systeme = d_es_processus;
636: return;
637: }
638: }
639:
640: if (close(pipes_erreur[0]) != 0)
641: {
642: (*s_etat_processus).erreur_systeme = d_es_processus;
643: return;
644: }
645: }
646:
647: return;
648: }
649:
650:
651: int
652: transliterated_fprintf(struct_processus *s_etat_processus, file *flux,
653: const char *format, ...)
654: {
655: int ios;
656:
657: unsigned char *tampon;
658: unsigned char *tampon2;
659:
660: va_list arguments;
661:
662: va_start(arguments, format);
663:
664: # ifdef OS2
665: unsigned char *ptr_e;;
666: unsigned char *ptr_l;;
667: unsigned char *tampon3;
668:
669: unsigned long i;
670: # endif
671:
672: if (valsprintf(&tampon, format, arguments) < 0)
673: {
674: va_end(arguments);
675:
676: if (s_etat_processus != NULL)
677: {
678: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
679: }
680:
681: return(-1);
682: }
683:
684: va_end(arguments);
685:
686: if (s_etat_processus != NULL)
687: {
688: if ((tampon2 = transliteration(s_etat_processus, tampon,
689: d_locale, (*s_etat_processus).localisation)) == NULL)
690: {
691: free(tampon);
692: return(-1);
693: }
694:
695: free(tampon);
696: }
697: else
698: {
699: tampon2 = tampon;
700: }
701:
702: # ifdef OS2
703: i = 0;
704: ptr_l = tampon2;
705:
706: while((*ptr_l) != d_code_fin_chaine)
707: {
708: if ((*ptr_l) == '\n')
709: {
710: i++;
711: }
712:
713: ptr_l++;
714: }
715:
716: if ((tampon3 = malloc((strlen(tampon2) + i + 1) * sizeof(unsigned char)))
717: == NULL)
718: {
719: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
720: return(NULL);
721: }
722:
723: ptr_e = tampon3;
724: ptr_l = tampon2;
725:
726: while((*ptr_l) != d_code_fin_chaine)
727: {
728: (*ptr_e) = (*ptr_l);
729:
730: if ((*ptr_l) == '\n')
731: {
732: (*(++ptr_e)) = '\r';
733: ptr_e++;
734: ptr_l++;
735: }
736: else
737: {
738: ptr_e++;
739: ptr_l++;
740: }
741: }
742:
743: (*ptr_e) = d_code_fin_chaine;
744:
745: free(tampon2);
746: tampon2 = tampon3;
747: # endif
748:
749: # ifdef SunOS
750: while((ios = fprintf(flux, "%s", tampon2)) < 0)
751: {
752: if ((errno != EINTR) && (errno != 0))
753: {
754: break;
755: }
756: }
757: # else
758: ios = fprintf(flux, "%s", tampon2);
759: # endif
760:
761: free(tampon2);
762:
763: return(ios);
764: }
765:
766:
767: int
768: tex_fprintf(struct_processus *s_etat_processus,
769: file *flux, const char *format, ...)
770: {
771: int ios;
772:
773: unsigned char *tampon;
774: unsigned char *tampon2;
775:
776: va_list arguments;
777:
778: va_start(arguments, format);
779:
780: if (valsprintf(&tampon, format, arguments) < 0)
781: {
782: va_end(arguments);
783:
784: if (s_etat_processus != NULL)
785: {
786: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
787: }
788:
789: return(-1);
790: }
791:
792: va_end(arguments);
793:
794: if ((tampon2 = transliteration(s_etat_processus, tampon,
795: d_locale, ds_tex_encodage_3)) == NULL)
796: {
797: free(tampon);
798: return(-1);
799: }
800:
801: free(tampon);
802:
803: # ifdef SunOS
804: while((ios = fprintf(flux, "%s", tampon2)) < 0)
805: {
806: if ((errno != EINTR) && (errno != 0))
807: {
808: break;
809: }
810: }
811: # else
812: ios = fprintf(flux, "%s", tampon2);
813: # endif
814:
815: free(tampon2);
816:
817: return(ios);
818: }
819:
820: #define fprintf NULL
821: #define printf NULL
822:
823: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>