1 /*
2 * This file is part of the Alliance CAD System
3 * Copyright (C) Laboratoire LIP6 - D�partement ASIM
4 * Universite Pierre et Marie Curie
5 *
6 * Home page : http://www-asim.lip6.fr/alliance/
7 * E-mail : mailto:alliance-users@asim.lip6.fr
8 *
9 * This library is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Library General Public License as published
11 * by the Free Software Foundation; either version 2 of the License, or (at
12 * your option) any later version.
13 *
14 * Alliance VLSI CAD System is distributed in the hope that it will be
15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17 * Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with the GNU C Library; see the file COPYING. If not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24 /*
25 * Purpose : system dependant functions
26 * Date : 06/03/92
27 * Author : Frederic Petrot <Frederic.Petrot@lip6.fr>
28 * Modified by Czo <Olivier.Sirol@lip6.fr> 1997,98
29 */
30
31 #ident "$Id: mbk_sys.c,v 1.5 2012/05/14 14:20:23 alliance Exp $"
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <sys/wait.h>
39 #include <string.h>
40 #include <fcntl.h>
41 #include <errno.h>
42
43 #include "mut.h"
44 #include "mbk_sys.h"
45
46 static char filename[BUFSIZ];
47 char MBKFOPEN_NAME[BUFSIZ];
48 char MBKFOPEN_FILTER;
49 endchld_list *HEAD_ENDCHLD=NULL;
50 endchld_list *HEAD_ENDCHLD_FREE=NULL;
51 int STAT_ENDCHLD;
52 autoackchld_list *HEAD_AUTOACKCHLD=NULL;
53 autoackchld_list *HEAD_AUTOACKCHLD_FREE=NULL;
54 int STAT_AUTOACKCHLD;
55
56 long mbkalloc_stat = 0; /* statistics on maximun allocated memory */
57
mbkalloc(size_t nbytes)58 void *mbkalloc(size_t nbytes)
59 {
60 void *pt;
61
62 mbkalloc_stat += nbytes;
63 if (!(pt = malloc(nbytes))) {
64 (void)fflush(stdout);
65 (void)fprintf(stderr,"*** mbk error ***\n");
66 (void)fprintf(stderr,"fatal mbkalloc error : not enough memory\n");
67 EXIT(1);
68 }
69 return pt;
70 }
71
mbkrealloc(void * pt,size_t nbytes)72 void *mbkrealloc(void *pt, size_t nbytes)
73 {
74
75 mbkalloc_stat += nbytes;
76 if (!(pt = realloc(pt, nbytes))) {
77 (void)fflush(stdout);
78 (void)fprintf(stderr,"*** mbk error ***\n");
79 (void)fprintf(stderr,"fatal mbkrealloc error : not enough memory\n");
80 EXIT(1);
81 }
82 return pt;
83 }
84
mbkfree(void * ptr)85 void mbkfree(void *ptr)
86 {
87 (void)free(ptr);
88 }
89
mbkgetenv(const char * name)90 char *mbkgetenv(const char *name)
91 {
92 char *value;
93
94 if (name == NULL)
95 fprintf(stdout, "--- mbk --- ERROR : mbkgetenv(NULL)\n");
96
97 value = getenv(name);
98
99 if (TRACE_GETENV) {
100 fprintf(stdout, "--- mbk --- mbkgetenv %s : %s\n",
101 name ? name : "NULL", value ? value : "NULL");
102 }
103
104 return value;
105 }
106
107
108 /* file opening :
109 defines the strategy used for searching and opening file in the
110 mbk environement. */
mbkfopen(const char * name,const char * extension,const char * mode)111 FILE* mbkfopen(const char *name, const char *extension, const char *mode)
112 {
113 FILE *ptf;
114
115 ptf = mbkfopentrace(name, extension, mode);
116 if(( TRACE_FILE == 1 ) || (( TRACE_FILE == 3 ) && (ptf != NULL )))
117 {
118 fflush( stdout );
119 fprintf( stderr,
120 "*** mbkfopen( \"%s\", \"%s\", \"%s\" ) -> %s\n",
121 name,
122 extension ? extension : "",
123 mode,
124 ptf ? MBKFOPEN_NAME : "FAILED"
125 );
126 }
127 return ptf;
128 }
129
mbkfopen_infos(const FILE * in,const char * filename,const char * name,const char * extension,const char * mode,const char filter)130 void mbkfopen_infos(const FILE *in, const char *filename, const char *name, const char *extension, const char *mode, const char filter)
131 {
132 if( in )
133 {
134 strcpy( MBKFOPEN_NAME, filename );
135 MBKFOPEN_FILTER = filter;
136 }
137
138 if( TRACE_FILE == 2 )
139 {
140 /* La methode de Czo : y parait qu'on peut debugger avec ca... */
141 fprintf( stdout,
142 "--- mbk --- mbkfopen %s : %s, (%s,%s,%s)\n",
143 in ? "ok" : "FAILED",
144 filename,
145 name,
146 extension ? extension : "",
147 mode
148 );
149 }
150 }
151
mbkfopentrace(const char * name,const char * extension,const char * mode)152 FILE *mbkfopentrace(const char *name, const char *extension, const char *mode)
153 {
154 FILE *in=NULL;
155 FILE *insav;
156 int i;
157
158
159 if (!CATA_LIB || !WORK_LIB)
160 mbkenv(); /* not done yet */
161
162
163 if( *mode == 'w' )
164 {
165 if( OUT_FILTER && FILTER_SFX )
166 {
167 if (extension)
168 (void)sprintf( filename,
169 "%s/%s.%s%s",
170 WORK_LIB,
171 name,
172 extension,
173 FILTER_SFX
174 );
175 else
176 (void)sprintf(filename, "%s/%s%s", WORK_LIB, name, FILTER_SFX );
177
178 strcpy( MBKFOPEN_NAME, filename );
179 in = mbkpopen( filename, OUT_FILTER, 'w' );
180 mbkfopen_infos( in, filename, name, extension, mode, YES );
181 if (extension)
182 (void)sprintf( filename,
183 "%s/%s.%s",
184 WORK_LIB,
185 name,
186 extension
187 );
188 else
189 (void)sprintf(filename, "%s/%s", WORK_LIB, name );
190 if((insav = fopen(filename,READ_TEXT)) != NULL)
191 {
192 fflush( stdout );
193 fprintf( stderr,
194 "*** mbk warning : file %s already exist in the drive directory\n", filename) ;
195 fprintf( stderr, "it will be deleted\n" ) ;
196 fflush( stderr );
197 unlink(filename) ;
198 fclose(insav) ;
199 }
200 return ( in );
201 }
202 else
203 {
204 if (extension)
205 (void)sprintf( filename,
206 "%s/%s.%s",
207 WORK_LIB,
208 name,
209 extension
210 );
211 else
212 (void)sprintf(filename, "%s/%s", WORK_LIB, name );
213
214 strcpy( MBKFOPEN_NAME, filename );
215 in = fopen( filename, WRITE_TEXT ) ;
216 mbkfopen_infos( in, filename, name, extension, mode, NO );
217 return ( in );
218 }
219 }
220 else
221 if( *mode == 'r' )
222 {
223 if (extension) /* if extension is null, no dot is required */
224 (void)sprintf( filename,
225 "%s/%s.%s",
226 WORK_LIB,
227 name,
228 extension
229 );
230 else
231 (void)sprintf(filename, "%s/%s", WORK_LIB, name);
232
233 in = fopen( filename, READ_TEXT );
234 mbkfopen_infos( in, filename, name, extension, mode, NO );
235 if( in )
236 {
237 if( FILTER_SFX && IN_FILTER )
238 {
239 if (extension) /* if extension is null, no dot is required */
240 (void)sprintf( filename,
241 "%s/%s.%s%s",
242 WORK_LIB,
243 name,
244 extension,
245 FILTER_SFX
246 );
247 else
248 (void)sprintf(filename, "%s/%s%s", WORK_LIB, name , FILTER_SFX);
249 if((insav = fopen(filename,READ_TEXT)) != NULL)
250 {
251 fflush( stdout );
252 fprintf( stderr,
253 "*** mbk warning : file %s also exist it will be ignored\n", filename) ;
254 fflush( stderr );
255 fclose(insav) ;
256 }
257 }
258 return in;
259 }
260
261 if( FILTER_SFX && IN_FILTER )
262 {
263 if (extension) /* if extension is null, no dot is required */
264 (void)sprintf( filename,
265 "%s/%s.%s%s",
266 WORK_LIB,
267 name,
268 extension,
269 FILTER_SFX
270 );
271 else
272 (void)sprintf(filename, "%s/%s%s", WORK_LIB, name, FILTER_SFX );
273
274 in = mbkpopen( filename, IN_FILTER, 'r' );
275 mbkfopen_infos( in, filename, name, extension, mode, YES );
276 if( in )
277 return in ;
278 }
279
280 i=0;
281
282 while (CATA_LIB[i])
283 {
284 if (extension)
285 (void)sprintf( filename,
286 "%s/%s.%s",
287 CATA_LIB[i],
288 name,
289 extension
290 );
291 else
292 (void)sprintf( filename,
293 "%s/%s",
294 CATA_LIB[i],
295 name
296 );
297
298 in = fopen( filename, READ_TEXT );
299 mbkfopen_infos( in, filename, name, extension, mode, NO );
300 if( in )
301 {
302 if( FILTER_SFX && IN_FILTER )
303 {
304 if (extension) /* if extension is null, no dot is required */
305 (void)sprintf( filename,
306 "%s/%s.%s%s",
307 CATA_LIB[i],
308 name,
309 extension ,
310 FILTER_SFX
311 );
312 else
313 (void)sprintf(filename, "%s/%s%s", CATA_LIB[i], name ,FILTER_SFX);
314 if((insav = fopen(filename,READ_TEXT)) != NULL)
315 {
316 fflush( stdout );
317 fprintf( stderr,
318 "*** mbk warning : file %s also exist it will be ignored\n", filename) ;
319 fflush( stderr );
320 fclose(insav) ;
321 }
322 }
323 return( in );
324 }
325
326 if( FILTER_SFX && IN_FILTER )
327 {
328 if (extension) /* if extension is null, no dot is required */
329 (void)sprintf( filename,
330 "%s/%s.%s%s",
331 CATA_LIB[i],
332 name,
333 extension,
334 FILTER_SFX
335 );
336 else
337 (void)sprintf(filename, "%s/%s%s", CATA_LIB[i], name, FILTER_SFX );
338
339 in = mbkpopen( filename, IN_FILTER, 'r' );
340 mbkfopen_infos( in, filename, name, extension, mode, YES );
341 if( in )
342 {
343 return in ;
344 }
345 }
346
347 i++;
348 }
349 return( NULL );
350 }
351 else
352 {
353 (void)fflush(stdout);
354 (void)fprintf(stderr, "*** mbk error ***\n");
355 (void)fprintf(stderr, "unknown file opening mode %s\n", mode);
356 EXIT(1);
357 }
358
359 return NULL; /* never reached */
360 }
361
362 /* unlink :
363 ensures that only files in the working library may be erased. */
mbkunlink(const char * name,const char * extension)364 int mbkunlink(const char *name, const char *extension)
365 {
366 if (!CATA_LIB || !WORK_LIB)
367 mbkenv(); /* not done yet */
368
369 if (extension) /* if extension is null, no dot is required */
370 (void)sprintf(filename, "%s/%s.%s", WORK_LIB, name, extension);
371 else
372 (void)sprintf(filename, "%s/%s", WORK_LIB, name);
373
374 return unlink(filename);
375 }
376
377 /* filepath :
378 find the complete path of file from mbkfopen point of view. */
filepath(const char * name,const char * extension)379 char *filepath(const char *name, const char *extension)
380 {
381 FILE *in;
382 int i ;
383
384 if (!CATA_LIB || !WORK_LIB)
385 mbkenv(); /* not done yet */
386
387 if (extension) /* if extension is null, no dot is required */
388 (void)sprintf(filename, "%s/%s.%s", WORK_LIB, name, extension );
389 else
390 (void)sprintf(filename, "%s/%s", WORK_LIB, name );
391
392 if ((in = fopen(filename, READ_TEXT))) {
393 (void)fclose(in);
394 return filename;
395 }
396
397 if( FILTER_SFX && IN_FILTER )
398 {
399 if (extension) /* if extension is null, no dot is required */
400 (void)sprintf(filename, "%s/%s.%s%s", WORK_LIB, name, extension, FILTER_SFX );
401 else
402 (void)sprintf(filename, "%s/%s%s", WORK_LIB, name, FILTER_SFX );
403
404 if ((in = fopen(filename, READ_TEXT))) {
405 (void)fclose(in);
406 return filename;
407 }
408 }
409
410
411 i = 0;
412 while (CATA_LIB[i]) {
413 if (extension) /* if extension is null, no dot is required */
414 (void)sprintf(filename, "%s/%s.%s", CATA_LIB[i], name, extension );
415 else
416 (void)sprintf(filename, "%s/%s", CATA_LIB[i], name );
417
418 if ((in = fopen(filename, READ_TEXT))) {
419 (void)fclose(in);
420 return filename;
421 }
422
423 if( FILTER_SFX && IN_FILTER )
424 {
425 if (extension) /* if extension is null, no dot is required */
426 (void)sprintf(filename, "%s/%s.%s%s", CATA_LIB[i], name, extension, FILTER_SFX );
427 else
428 (void)sprintf(filename, "%s/%s%s", CATA_LIB[i], name, FILTER_SFX );
429
430 if ((in = fopen(filename, READ_TEXT))) {
431 (void)fclose(in);
432 return filename;
433 }
434 }
435 i++;
436 }
437 return NULL;
438 }
439
440 /* mbkpopen : open a pipe with a filter, return a FILE*
441 * Gregoire.Avot
442 */
443
mbkpopen(const char * nom,const char * filter,char mode)444 FILE* mbkpopen(const char *nom, const char *filter, char mode)
445 {
446 int ptf[2];
447 static int fic;
448 int pid;
449 FILE *file;
450 char **argv;
451
452 if( mode == 'w' )
453 fic = open( nom,
454 O_WRONLY|O_CREAT|O_TRUNC,
455 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
456 );
457 else
458 fic = open( nom, O_RDONLY );
459
460 if( fic == -1 )
461 return( NULL );
462
463 if( pipe( ptf ) == -1 )
464 {
465 fflush( stdout );
466 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" )\n", nom );
467 perror( "pipe() ");
468 EXIT(1);
469 }
470
471 #ifndef AUTO_HAS_VFORK
472 pid = fork();
473 #else
474 pid = vfork();
475 #endif
476
477 if( pid == -1 )
478 {
479 fflush( stdout );
480 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" )\n", nom );
481 perror( "(v)fork() ");
482 EXIT(1);
483 }
484
485 if( pid == 0 )
486 {
487 /* fils */
488 fflush( stdout );
489
490 argv = decompfilter( filter );
491 if( argv == NULL )
492 {
493 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
494 fprintf( stderr, "Bad filter.\n" );
495 EXIT(1);
496 }
497
498 if( mode == 'w' )
499 {
500 if( dup2( ptf[0], 0 ) == -1 )
501 {
502 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
503 perror( "dup2( ptf[0], 0 ) ");
504 EXIT(1);
505 }
506
507 if( dup2( fic, 1 ) == -1 )
508 {
509 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
510 perror( "dup2( fic, 1 ) ");
511 EXIT(1);
512 }
513 }
514 else
515 {
516 if( dup2( ptf[1], 1 ) == -1 )
517 {
518 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
519 perror( "dup2( ptf[1], 1 ) ");
520 EXIT(1);
521 }
522
523 if( dup2( fic, 0 ) == -1 )
524 {
525 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
526 perror( "dup2( fic, 0 ) ");
527 EXIT(1);
528 }
529 }
530
531 if( close( fic ) == -1 )
532 {
533 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
534 perror( "close( fic ) ");
535 EXIT(1);
536 }
537
538 if( close( ptf[1] ) == -1 )
539 {
540 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
541 perror( "close( ptf[1] ) ");
542 EXIT(1);
543 }
544
545 if( close( ptf[0] ) == -1 )
546 {
547 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
548 perror( "close( ptf[0] ) ");
549 EXIT(1);
550 }
551
552 if( execvp( argv[0], &(argv[1]) ) == -1 )
553 {
554 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom );
555 perror( "execvp " );
556 EXIT(1);
557 }
558 }
559
560 mbksetautoackchld( pid );
561 close( fic );
562
563 if( mode == 'w' )
564 {
565 if( close( ptf[0] ) == -1 )
566 {
567 fflush( stdout );
568 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) parent\n", nom );
569 perror( "close( ptf[0] ) ");
570 EXIT(1);
571 }
572
573 file = fdopen( ptf[1], "w" );
574 if( file == NULL )
575 {
576 fflush( stdout );
577 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) parent\n", nom );
578 perror( "fdopen( ptf[1], \"w\" ) ");
579 EXIT(1);
580 }
581 }
582 else
583 {
584 if( close( ptf[1] ) == -1 )
585 {
586 fflush( stdout );
587 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) parent\n", nom );
588 perror( "close( ptf[1] ) ");
589 EXIT(1);
590 }
591
592 file = fdopen( ptf[0], "r" );
593 if( file == NULL )
594 {
595 fflush( stdout );
596 fprintf( stderr, "*** Fatal error in mbkpopen( \"%s\" ) parent\n", nom );
597 perror( "fdopen( ptf[0], \"r\" ) ");
598 EXIT(1);
599 }
600 }
601
602 return( file );
603 }
604
decompfilter(const char * filter)605 char **decompfilter( const char *filter )
606 {
607 int pos;
608 int i;
609 char *pt;
610 char *fullpath;
611 char *argv0;
612 char *argvn;
613 chain_list *head;
614 chain_list *scan;
615 int nbarg;
616 char **ret;
617
618 /* remove trailing space */
619 for( pos = 0 ; filter[pos] == ' ' && filter[pos] != 0 ; pos++ );
620 if( filter[pos] == 0 )
621 return( NULL );
622
623 /* The full path to binairie */
624 for( i = pos ; filter[i] != ' ' && filter[i] != 0 ; i++ );
625 fullpath = (char*)mbkalloc( sizeof(char) * ( i-pos+1 ) );
626 strncpy( fullpath, filter+pos, i-pos );
627 fullpath[i-pos] = 0;
628 pos = i;
629
630 /* The binairie himself */
631 pt = strrchr( fullpath, '/' );
632 argv0 = (char*)mbkalloc( sizeof( char ) * (strlen( fullpath ) + 1) );
633 if( pt == NULL )
634 strcpy( argv0, fullpath );
635 else
636 strcpy( argv0, pt+sizeof(char) );
637
638 /* The arguments */
639 head = NULL;
640 nbarg=2;
641
642 do
643 {
644 for( ; filter[pos] == ' ' && filter[pos] != 0 ; pos++ );
645 if( filter[pos] == 0 )
646 break;
647
648 for( i = pos ; filter[i] != ' ' && filter[i] != 0 ; i++ );
649 argvn = (char*)mbkalloc( sizeof( char ) * ( i-pos+1 ) );
650 strncpy( argvn, filter+pos, i-pos );
651 argvn[i-pos] = 0;
652 pos = i;
653 head = addchain( head, argvn );
654 nbarg++;
655 }
656 while( 1 );
657
658 head = reverse( head );
659
660 ret = (char**)mbkalloc( sizeof(char*) * (nbarg+1) );
661
662 ret[0] = fullpath;
663 ret[1] = argv0;
664
665 for( scan = head, pos=2 ; scan ; scan = scan->NEXT, pos++ )
666 ret[pos] = scan->DATA;
667 ret[pos] = NULL;
668
669 freechain( head );
670
671 return( ret );
672 }
673
mbkackchld(int sig)674 void mbkackchld( int sig )
675 {
676 int pid;
677 int status;
678 endchld_list *new;
679 int err;
680 autoackchld_list *scanauto, *prevauto;
681
682 /* Le handlert d'interruption SIGCHLD. Il doit avoir �t� configur� pour ne
683 * pas �tre interrompu par lui m�me. */
684
685 if( sig != SIGCHLD )
686 {
687 fflush( stdout );
688 fprintf( stderr,
689 "*** mbk warning : call of mbkackchld with signal %d\n",
690 (int)sig
691 );
692 return;
693 }
694
695 do
696 {
697 errno = 0;
698 pid = waitpid( -1, &status, WNOHANG );
699 err = errno ;
700 if( pid > 0 )
701 {
702 for( scanauto = HEAD_AUTOACKCHLD, prevauto=NULL ;
703 scanauto ;
704 scanauto = scanauto->NEXT
705 )
706 {
707 if( scanauto->PID == pid )
708 break;
709 prevauto = scanauto ;
710 }
711
712 if( scanauto )
713 {
714 /* Process was previously put in the list auto acknowledge. */
715 if( prevauto )
716 prevauto->NEXT = scanauto->NEXT;
717 else
718 HEAD_AUTOACKCHLD = scanauto->NEXT;
719
720 mbkfreeautoackchld( scanauto );
721 }
722 else
723 {
724 /* Put process in the waiting queue to be read by user */
725 new = mbkgetendchld();
726 new->NEXT = HEAD_ENDCHLD;
727 HEAD_ENDCHLD = new;
728 new->PID = pid;
729 new->STATUS = status;
730 }
731 }
732 }
733 while( pid != 0 && err != ECHILD );
734
735 }
736
737 /* Sur les architectures multipro, on peut avoir un malloc() interrompu par
738 * un signal. Si ou alloue une structure endchld_list avec un malloc dans le
739 * handler, on aura une r�entrance du malloc. Cette caract�ristiques n'est pour
740 * l'instant pas support�e. */
741
mbkgetendchld(void)742 endchld_list* mbkgetendchld( void )
743 {
744 endchld_list *new;
745
746 /* Cette fonction ne doit �tre appell�e qu'� partir du handler du signal
747 * SIGCHLD. Si cela devait changer, il faudrait la prot�ger contre la
748 * r�ception de ce signal */
749
750 if( ! HEAD_ENDCHLD_FREE )
751 {
752 fflush( stdout );
753 fprintf( stderr,
754 "\n*** mbk ERROR : Not enought free slot in mbkgetfreeendchld().\n"
755 );
756 exit(1);
757 }
758
759 new = HEAD_ENDCHLD_FREE ;
760 HEAD_ENDCHLD_FREE = HEAD_ENDCHLD_FREE->NEXT ;
761
762 STAT_ENDCHLD++;
763 return( new );
764 }
765
mbkfreeendchld(endchld_list * bloc)766 void mbkfreeendchld( endchld_list *bloc )
767 {
768 sigset_t set;
769
770 /* Cette fonction est appell�e � partir de mbkwaitpid(). Il peut y avoir une
771 * corruption de la liste si un signal SIGCHLD intervient entre les deux
772 * lignes puisque le handler appellera mbkgetendchld... */
773
774 /* On masque temporairement le signal emb�tant */
775 sigemptyset( &set );
776 sigaddset( &set, SIGCHLD );
777 sigprocmask( SIG_BLOCK, &set, NULL );
778
779
780 bloc->NEXT = HEAD_ENDCHLD_FREE ;
781 HEAD_ENDCHLD_FREE = bloc ;
782
783 STAT_ENDCHLD--;
784 /* On le demasque. Si il y en a un qui est arriv� entre temps, il sera pris
785 * en compte maintenant. */
786 /* sigrelse(SIGCHLD); (non d�fini sous SunOs) */
787 sigprocmask( SIG_UNBLOCK, &set, NULL );
788 }
789
mbkinitendchld()790 void mbkinitendchld( )
791 {
792 endchld_list *bloc;
793 int n;
794
795 /* L�, pas de probl�mes : le handler n'est pas encore positionn� quand cette
796 * fonction est appell�e. */
797 bloc = (endchld_list*)mbkalloc( sizeof( endchld_list ) * ENDCHLD_MAX );
798 n = ENDCHLD_MAX - 1;
799 bloc[n].NEXT = NULL ;
800 while( n > 0 )
801 {
802 n-- ;
803 bloc[n].NEXT = &( bloc[n+1] );
804 }
805 HEAD_ENDCHLD_FREE = &(bloc[0]);
806 STAT_ENDCHLD=0;
807 }
808
mbkgetautoackchld(void)809 autoackchld_list* mbkgetautoackchld( void )
810 {
811 autoackchld_list *new;
812
813 if( ! HEAD_AUTOACKCHLD_FREE )
814 {
815 fflush( stdout );
816 fprintf( stderr,
817 "\n*** mbk ERROR : Not enought free slot in mbkgetautoackchld().\n"
818 );
819 exit(1);
820 }
821
822 new = HEAD_AUTOACKCHLD_FREE ;
823 HEAD_AUTOACKCHLD_FREE = HEAD_AUTOACKCHLD_FREE->NEXT ;
824
825 STAT_AUTOACKCHLD++;
826 return( new );
827 }
828
mbkfreeautoackchld(autoackchld_list * bloc)829 void mbkfreeautoackchld( autoackchld_list *bloc )
830 {
831 bloc->NEXT = HEAD_AUTOACKCHLD_FREE ;
832 HEAD_AUTOACKCHLD_FREE = bloc ;
833 STAT_AUTOACKCHLD--;
834 }
835
mbkinitautoackchld(void)836 void mbkinitautoackchld( void )
837 {
838 autoackchld_list *bloc;
839 int n;
840
841 bloc=(autoackchld_list*)mbkalloc( sizeof( autoackchld_list ) * ENDCHLD_MAX );
842 n = AUTOACKCHLD_MAX - 1;
843 bloc[n].NEXT = NULL ;
844 while( n > 0 )
845 {
846 n-- ;
847 bloc[n].NEXT = &( bloc[n+1] );
848 }
849 HEAD_AUTOACKCHLD_FREE = &(bloc[0]);
850 STAT_AUTOACKCHLD=0;
851 }
852
mbksetautoackchld(int pid)853 void mbksetautoackchld( int pid )
854 {
855 endchld_list *scan, *prev ;
856 autoackchld_list *new;
857 sigset_t set;
858
859 /* Fonction utilisateur : on met dans la liste HEAD_AUTOACKCHLD un num�ro de
860 * pid. D�s qu'un processus fils se termine ave ce pid, il sera
861 * automatiquement supprim�. */
862
863 /* Dans le d�roulement normal du programme, on touche ici � des structures
864 * qui sont modifi�es par le handler SIGCHLD. On �vite de mettre le bazard en
865 * blindant le morceau de code. */
866
867 sigemptyset( &set );
868 sigaddset( &set, SIGCHLD );
869 sigprocmask( SIG_BLOCK, &set, NULL );
870
871 prev = NULL;
872 for( scan = HEAD_ENDCHLD ; scan ; scan = scan->NEXT )
873 {
874 if( scan->PID == pid )
875 break;
876 prev = scan;
877 }
878
879 if( scan )
880 {
881 /* Cas o� le processus que l'on demande d'acquiter automatiquement est d�j�
882 * termin�. Dans ce cas on le supprime de la file d'attente des processus
883 * termin�s */
884
885 if( prev )
886 prev->NEXT = scan->NEXT ;
887 else
888 HEAD_ENDCHLD = scan->NEXT ;
889
890 mbkfreeendchld( scan );
891 }
892 else
893 {
894 /* On ne voudra jamais savoir ce qu'est devenu le processus fils pid. On le
895 * met dans la liste des processus � acquiter automatiquement */
896 new = mbkgetautoackchld();
897 new->PID = pid;
898 new->NEXT = HEAD_AUTOACKCHLD ;
899 HEAD_AUTOACKCHLD = new ;
900 }
901 sigprocmask( SIG_UNBLOCK, &set, NULL );
902 }
903