![]() ![]() | ![]() |
1.1 bertrand 1: /*
2: ================================================================================
1.20 ! bertrand 3: RPL/2 (R) version 4.0.19
1.1 bertrand 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:
1.14 bertrand 23: #include "rpl-conv.h"
24: #include "tex-conv.h"
1.5 bertrand 25:
1.1 bertrand 26: #include <stdarg.h>
1.5 bertrand 27:
1.1 bertrand 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);
1.3 bertrand 127: free(chaine_sortie);
128:
1.1 bertrand 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: --------------------------------------------------------------------------------
1.17 bertrand 162: iorties :
1.1 bertrand 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:
1.9 bertrand 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
1.1 bertrand 415: {
416: (*s_etat_processus).erreur_systeme = d_es_processus;
417: return;
418: }
419:
420: if (waitpid(pid, &status, 0) == -1)
421: {
1.9 bertrand 422: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 423: if (sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
1.9 bertrand 424: # else
425: if (sem_wait((*s_etat_processus).semaphore_fork) == -1)
426: # endif
1.1 bertrand 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:
1.9 bertrand 439: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 440: if (sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
1.9 bertrand 441: # else
442: if (sem_wait((*s_etat_processus).semaphore_fork) == -1)
443: # endif
1.1 bertrand 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:
1.18 bertrand 464: tampon[0] = d_code_fin_chaine;
465:
1.9 bertrand 466: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 467: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
1.9 bertrand 468: # else
469: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
470: # endif
1.1 bertrand 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: {
1.9 bertrand 480: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 481: while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
1.9 bertrand 482: # else
483: while(sem_wait((*s_etat_processus).semaphore_fork) == -1)
484: # endif
1.1 bertrand 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:
1.9 bertrand 506: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 507: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
1.9 bertrand 508: # else
509: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
510: # endif
1.1 bertrand 511: {
512: (*s_etat_processus).erreur_systeme = d_es_processus;
513: return;
514: }
515: }
516:
1.9 bertrand 517: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 518: while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
1.9 bertrand 519: # else
520: while(sem_wait((*s_etat_processus).semaphore_fork) == -1)
521: # endif
1.1 bertrand 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:
1.17 bertrand 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: }
1.1 bertrand 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:
1.9 bertrand 587: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 588: if (sem_post(&((*s_etat_processus).semaphore_fork)) != 0)
1.9 bertrand 589: # else
590: if (sem_post((*s_etat_processus).semaphore_fork) != 0)
591: # endif
1.1 bertrand 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:
1.18 bertrand 601: free(tampon);
602:
603: if (((*s_etat_processus).localisation = malloc((strlen(d_locale)
604: + 1) * sizeof(unsigned char))) == NULL)
1.1 bertrand 605: {
1.18 bertrand 606: (*s_etat_processus).erreur_systeme = d_es_processus;
607: return;
1.1 bertrand 608: }
609:
1.18 bertrand 610: strcpy((*s_etat_processus).localisation, d_locale);
1.1 bertrand 611: }
612:
1.9 bertrand 613: # ifndef SEMAPHORES_NOMMES
1.1 bertrand 614: while(sem_wait(&((*s_etat_processus).semaphore_fork)) == -1)
1.9 bertrand 615: # else
616: while(sem_wait((*s_etat_processus).semaphore_fork) == -1)
617: # endif
1.1 bertrand 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;
1.5 bertrand 642:
643: unsigned char *tampon;
1.1 bertrand 644: unsigned char *tampon2;
1.5 bertrand 645:
1.1 bertrand 646: va_list arguments;
647:
648: va_start(arguments, format);
649:
1.17 bertrand 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:
1.5 bertrand 658: if (valsprintf(&tampon, format, arguments) < 0)
1.1 bertrand 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:
1.17 bertrand 688: # ifdef OS2
689: i = 0;
690: ptr_l = tampon2;
691:
692: while((*ptr_l) != d_code_fin_chaine)
693: {
694: if ((*ptr_l) == '\n')
695: {
696: i++;
697: }
698:
699: ptr_l++;
700: }
701:
702: if ((tampon3 = malloc((strlen(tampon2) + i + 1) * sizeof(unsigned char)))
703: == NULL)
704: {
705: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
706: return(NULL);
707: }
708:
709: ptr_e = tampon3;
710: ptr_l = tampon2;
711:
712: while((*ptr_l) != d_code_fin_chaine)
713: {
714: (*ptr_e) = (*ptr_l);
715:
716: if ((*ptr_l) == '\n')
717: {
718: (*(++ptr_e)) = '\r';
719: ptr_e++;
720: ptr_l++;
721: }
722: else
723: {
724: ptr_e++;
725: ptr_l++;
726: }
727: }
728:
729: (*ptr_e) = d_code_fin_chaine;
730:
731: free(tampon2);
732: tampon2 = tampon3;
733: # endif
734:
1.1 bertrand 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:
1.5 bertrand 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:
1.19 bertrand 806:
807: unsigned char *
808: readline_wrapper(unsigned char *invite)
809: {
810: unsigned char *chaine;
811: unsigned char *i;
812:
813: chaine = readline(invite);
814: printf("\r");
815:
816: return(chaine);
817: }
818:
819:
1.1 bertrand 820: #define fprintf NULL
821: #define printf NULL
822:
823: // vim: ts=4