2 * This file is part of the Alliance CAD System
3 * Copyright (C) Laboratoire LIP6 - Département ASIM
4 * Universite Pierre et Marie Curie
6 * Home page : http://www-asim.lip6.fr/alliance/
7 * E-mail support : mailto:alliance-support@asim.lip6.fr
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.
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.
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., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * Purpose : system dependant functions
27 * Author : Frederic Petrot <Frederic.Petrot@lip6.fr>
28 * Modified by Czo <Olivier.Sirol@lip6.fr> 1997,98
31 #ident "$Id: mbk_sys.c,v 1.69 2008/09/22 14:34:15 anthony Exp $"
36 #include <sys/types.h>
47 // zinaps: to compute the memory consumed
55 #define _STRUCTURED_PROC 1
56 #include <sys/procfs.h>
63 #ifdef MALLOC_HISTOGRAM
73 #include <sys/sysctl.h>
74 #include <mach/task.h>
75 #include <mach/mach_init.h>
76 #include <mach/shared_memory_server.h>
80 #define VFORKMAXTRY 100
82 static char filename
[BUFSIZ
];
83 char MBKFOPEN_NAME
[BUFSIZ
];
85 autoackchld_list
*HEAD_AUTOACKCHLD
=NULL
;
86 autoackchld_list
*HEAD_AUTOACKCHLD_FREE
=NULL
;
89 it
* MBK_TAB_FILE_ACCES
=NULL
;
91 long mbkalloc_stat
= 0; /* statistics on maximun allocated memory */
93 void *mbkalloc(nbytes
)
98 mbkalloc_stat
+= nbytes
;
99 if (!(pt
= malloc(nbytes
))) {
100 avt_errmsg (MBK_ERRMSG
, "045", AVT_FATAL
,(unsigned long)nbytes
,mbkprocessmemoryusage()/(unsigned long)1024);
105 void *mbkrealloc(pt
, nbytes
)
110 mbkalloc_stat
+= nbytes
;
111 if (!(pt
= realloc(pt
, nbytes
))) {
112 avt_errmsg (MBK_ERRMSG
, "046", AVT_FATAL
);
121 (void)free((char *)ptr
);
123 (void)free(ptr
); /* lint makes a mistake here : expects (char *) */
128 defines the strategy used for searching and opening file in the
130 FILE* mbkfopen( name
, extension
, mode
)
135 return mbkfopen_ext( name
, extension
, mode
, 0, 1 );
138 FILE* mbkfopen_ext( name
, extension
, mode
, access
, allowcompress
)
148 // Check name contain extension
151 le
= strlen( extension
);
152 for( i
=ln
-1, j
=le
-1 ; i
>=0 && j
>=0 && name
[i
] == extension
[j
] ; i
--, j
-- );
157 ptf
= mbkfopentrace( name
, extension
, mode
, access
, allowcompress
);
159 avt_log( LOGFILEACCESS
, 1,
160 "open( \"%s\", \"%s\", \"%s\" ) -> %s [%s]\n",
162 extension
? extension
: "",
164 ptf
? MBKFOPEN_NAME
: "FAILED",
165 mbk_getfileacces( ptf
) == MBK_FILE_STD
? "STD" : "LFS"
170 void mbkfopen_infos( in
, filename
, name
, extension
, mode
)
177 avt_log( LOGFILEACCESS
, 2,
178 "%s : %s, (%s,%s,%s)\n",
179 in
? "ok" : "FAILED",
182 extension
? extension
: "",
187 /*******************************************************************************
189 Fonctions d'accès aux fichiers en 32 ou en 64 bits dans un environnement 32
194 En écriture, le mode 64 est toujours utilisé.
196 En lecture, si la taille du fichier est inférieure à MBK_LIMIT_USELARGEFILE,
197 le mode 32 bits est utilisé, sinon, c'est le mode 64.
198 Pour savoir en quel mode a été ouvert un fichier, il faut utiliser
199 mbk_getfileacces, qui renvoit MBK_FILE_STD ou MBK_FILE_LFS.
200 Lorsque le programme est compilé en 64 bits, le mode MBK_FILE_STD est toujours
201 utilisé puisque les fonctions de base accèdent en mode natif à des fichiers
203 MBK_OFFSET_STD et MBK_OFFSET_LFS sont les types qui permettent de stocker les
204 offsets, selon le mode renvoyer par mbk_getfileacces(). L'objet MBK_OFFSET_STD
205 est stockable dans un long.
207 Fonctions de positionnement dans un fichier.
209 mbkftell() et mbkfseek() permettent d'appeller les fonctions fseek et ftell sans
210 se soucier du mode d'acces au fichier. Les offsets étant de taille variable, ils
211 sont passés par pointeur. Le type MBK_OFFSET_MAX est un type qui permet de
212 stocker n'importe quelle taille d'offset.
214 *******************************************************************************/
216 void mbk_setfileacces( FILE *file
, char acces
)
220 if( ! MBK_TAB_FILE_ACCES
)
221 MBK_TAB_FILE_ACCES
= addit( 10 );
223 setititem( MBK_TAB_FILE_ACCES
, fileno( file
), (long)acces
);
226 char mbk_getfileacces( FILE *file
)
228 if( !file
|| !MBK_TAB_FILE_ACCES
) return 0;
229 return (char)getititem( MBK_TAB_FILE_ACCES
, fileno( file
) );
232 // Renvoie 1 en cas de succès, 0 en cas d'echec.
233 int mbkftell( FILE *file
, MBK_OFFSET_MAX
*offset
)
236 #if defined(_LARGEFILE64_SOURCE ) && !defined(_LP64)
237 if( mbk_getfileacces( file
) == MBK_FILE_STD
) {
238 *((MBK_OFFSET_STD
*)offset
) = ftell( file
);
239 if( *((MBK_OFFSET_STD
*)offset
) == (MBK_OFFSET_STD
)-1 )
243 *((MBK_OFFSET_LFS
*)offset
) = ftello64( file
);
244 if( *((MBK_OFFSET_LFS
*)offset
) == (MBK_OFFSET_LFS
)-1 )
248 *((MBK_OFFSET_STD
*)offset
) = ftell( file
);
249 if( *((MBK_OFFSET_STD
*)offset
) == (MBK_OFFSET_STD
)-1 )
256 // Renvoie 1 en cas de succès, 0 en cas d'echec.
257 int mbkfseek( FILE *file
, MBK_OFFSET_MAX
*offset
, int whence
)
260 #if defined(_LARGEFILE64_SOURCE ) && !defined(_LP64)
261 if( mbk_getfileacces( file
) == MBK_FILE_STD
)
262 r
= fseek( file
, *((MBK_OFFSET_STD
*)offset
), whence
);
264 r
= fseeko64( file
, *((MBK_OFFSET_LFS
*)offset
), whence
);
266 r
= fseek( file
, *((MBK_OFFSET_STD
*)offset
), whence
);
274 long long unsigned mbk_getfilesize( char *name
)
276 #if defined(_LARGEFILE64_SOURCE ) && !defined(_LP64)
280 r
=stat64( name
, &infos
);
282 return (long long unsigned) infos
.st_size
;
287 r
=stat( name
, &infos
);
289 if( errno
== EOVERFLOW
) {
290 avt_errmsg (MBK_ERRMSG
, "047", AVT_FATAL
, name
);
294 return (long long unsigned) infos
.st_size
;
298 FILE *mbksysfopen( char *name
, char *mode
, char access
)
302 if( strchr(mode
,'w')!=NULL
|| strchr(mode
,'a')!=NULL
) {
303 #if defined(_LARGEFILE64_SOURCE ) && !defined(_LP64)
307 file
= fopen64( name
, mode
);
308 mbk_setfileacces( file
, MBK_FILE_LFS
);
311 file
= fopen( name
, mode
);
312 mbk_setfileacces( file
, MBK_FILE_STD
);
315 avt_errmsg (MBK_ERRMSG
, "048", AVT_FATAL
);
318 file
= fopen( name
, mode
);
319 mbk_setfileacces( file
, MBK_FILE_STD
);
323 #if defined(_LARGEFILE64_SOURCE ) && !defined(_LP64)
325 if( mbk_getfilesize( filename
) > MBK_LIMIT_USELARGEFILE
) {
326 file
= fopen64( name
, mode
);
327 mbk_setfileacces( file
, MBK_FILE_LFS
);
330 file
= fopen( name
, mode
);
331 mbk_setfileacces( file
, MBK_FILE_STD
);
335 if( access
== MBK_FILE_LFS
) {
336 file
= fopen64( name
, mode
);
337 mbk_setfileacces( file
, MBK_FILE_LFS
);
340 file
= fopen( name
, mode
);
341 mbk_setfileacces( file
, MBK_FILE_STD
);
345 file
= fopen( name
, mode
);
346 mbk_setfileacces( file
, MBK_FILE_STD
);
354 /******************************************************************************/
356 // Ouvre un fichier. Le nom UNIX de ce fichier est stocké dans la variable
357 // global MBKFOPEN_NAME.
359 FILE *mbkfopentrace(name
, extension
, mode
, access
, allowcompress
)
360 char *name
, *extension
, *mode
;
361 char access
, allowcompress
;
366 char suffix
[512], suffixfilter
[512] ;
367 char filenamefilter
[BUFSIZE
];
368 char *prefixlist
[64];
371 if (!CATA_LIB
|| !WORK_LIB
)
372 mbkenv(); /* not done yet */
374 if( *mode
!= 'r' && *mode
!='w' && *mode
!='a') {
377 "Fatal error in mbkfopentrace() : unknown mode %s\n",
383 if( *mode
== 'w' || *mode
== 'a' || mode
[1] == 'l' )
388 if (*mode
== 'a') allowcompress
=0;
390 // Le tableau prefixlist contient la liste des répertoires où acceder les
398 prefixlist
[0] = WORK_LIB
;
400 prefixlist
[1] = NULL
;
404 while (CATA_LIB
[i
]) {
405 prefixlist
[i
+1] = CATA_LIB
[i
];
408 prefixlist
[i
+1] = NULL
;
412 // Accès aux fichiers
414 while( prefixlist
[i
] ) {
417 sprintf( suffix
, ".%s", extension
);
421 if( ( ( OUT_FILTER
&& *mode
== 'w' ) || ( IN_FILTER
&& *mode
== 'r' ))
422 && FILTER_SFX
&& allowcompress
)
423 sprintf( suffixfilter
, "%s", FILTER_SFX
);
425 suffixfilter
[0]='\0';
427 if (strcmp(prefixlist
[i
],"")!=0)
429 sprintf( filename
, "%s/%s%s", prefixlist
[i
], name
, suffix
);
430 sprintf( filenamefilter
, "%s/%s%s%s", prefixlist
[i
],
438 sprintf( filename
, "%s%s", name
, suffix
);
439 sprintf( filenamefilter
, "%s%s%s", name
,
445 if (V_STR_TAB
[__AVT_EXCLUDE_COMPRESSION
].VALUE
!=NULL
&& *mode
=='w')
449 strcpy(buf
, V_STR_TAB
[__AVT_EXCLUDE_COMPRESSION
].VALUE
);
450 tok
=strtok_r(buf
, " ", &c
);
453 if (mbk_TestREGEX(filename
, tok
))
455 suffixfilter
[0]='\0';
458 tok
=strtok_r(NULL
, " ", &c
);
462 // Stratégies différentes selon le mode d'ouverture :
463 // Ecriture : le format preféré est le compressé, l'autre est effacé
464 // Lecture : le format préféré est le non compressé, l'autre est ignoré
468 in
= mbksysfopen( filename
, "r", access
);
469 mbkfopen_infos( in
, filename
, name
, extension
, mode
);
471 if( suffixfilter
[0] ) {
472 infilter
= mbkpopen( filenamefilter
, IN_FILTER
, 'r' );
473 mbkfopen_infos( infilter
, filenamefilter
, name
, extension
, mode
);
478 if( in
&& infilter
) {
479 avt_errmsg (MBK_ERRMSG
, "049", AVT_WARNING
, filename
, filenamefilter
);
484 else if ( *mode
== 'w' || *mode
== 'a') {
486 if( suffixfilter
[0] ) {
487 infilter
= mbkpopen( filenamefilter
, OUT_FILTER
, 'w' );
488 mbkfopen_infos( infilter
, filenamefilter
, name
, extension
, mode
);
489 in
= mbksysfopen( filename
, "r", access
);
490 mbkfopen_infos( in
, filename
, name
, extension
, mode
);
494 in
= mbksysfopen( filename
, *mode
== 'a'?"a":"w", access
);
495 mbkfopen_infos( in
, filename
, name
, extension
, mode
);
498 if( in
&& infilter
) {
499 avt_errmsg (MBK_ERRMSG
, "050", AVT_WARNING
, filenamefilter
, filename
);
507 strcpy( MBKFOPEN_NAME
, filenamefilter
);
508 MBKFOPEN_FILTER
= YES
;
513 strcpy( MBKFOPEN_NAME
, filename
);
514 MBKFOPEN_FILTER
= NO
;
524 ensures that only files in the working library may be erased. */
525 int mbkunlink(name
, extension
)
526 char *name
, *extension
;
528 if (!CATA_LIB
|| !WORK_LIB
)
529 mbkenv(); /* not done yet */
531 if (extension
) /* if extension is null, no dot is required */
532 (void)sprintf(filename
, "%s/%s.%s", WORK_LIB
, name
, extension
);
534 (void)sprintf(filename
, "%s/%s", WORK_LIB
, name
);
536 return unlink(filename
);
540 find the complete path of file from mbkfopen point of view. */
541 char *filepath(name
, extension
)
542 char *name
, *extension
;
547 if (!CATA_LIB
|| !WORK_LIB
)
548 mbkenv(); /* not done yet */
552 le
= strlen( extension
);
553 for( i
=ln
-1, j
=le
-1 ; i
>=0 && j
>=0 && name
[i
] == extension
[j
] ; i
--, j
-- );
560 if( extension
) sprintf(filename
, "%s.%s", name
, extension
);
561 else sprintf(filename
, "%s", name
);
563 if ((in
= mbksysfopen(filename
, READ_TEXT
, 0))) {
568 if( FILTER_SFX
&& IN_FILTER
) {
569 if( extension
) sprintf(filename
, "%s.%s%s", name
, extension
, FILTER_SFX
);
570 else sprintf(filename
, "%s%s", name
, FILTER_SFX
);
572 if ((in
= mbksysfopen(filename
, READ_TEXT
, 0))) {
580 if (extension
) /* if extension is null, no dot is required */
581 (void)sprintf(filename
, "%s/%s.%s", WORK_LIB
, name
, extension
);
583 (void)sprintf(filename
, "%s/%s", WORK_LIB
, name
);
585 if ((in
= mbksysfopen(filename
, READ_TEXT
, 0))) {
590 if( FILTER_SFX
&& IN_FILTER
)
592 if (extension
) /* if extension is null, no dot is required */
593 (void)sprintf(filename
, "%s/%s.%s%s", WORK_LIB
, name
, extension
, FILTER_SFX
);
595 (void)sprintf(filename
, "%s/%s%s", WORK_LIB
, name
, FILTER_SFX
);
597 if ((in
= mbksysfopen(filename
, READ_TEXT
, 0))) {
605 while (CATA_LIB
[i
]) {
606 if (extension
) /* if extension is null, no dot is required */
607 (void)sprintf(filename
, "%s/%s.%s", CATA_LIB
[i
], name
, extension
);
609 (void)sprintf(filename
, "%s/%s", CATA_LIB
[i
], name
);
611 if ((in
= mbksysfopen(filename
, READ_TEXT
, 0))) {
616 if( FILTER_SFX
&& IN_FILTER
)
618 if (extension
) /* if extension is null, no dot is required */
619 (void)sprintf(filename
, "%s/%s.%s%s", CATA_LIB
[i
], name
, extension
, FILTER_SFX
);
621 (void)sprintf(filename
, "%s/%s%s", CATA_LIB
[i
], name
, FILTER_SFX
);
623 if ((in
= mbksysfopen(filename
, READ_TEXT
, 0))) {
635 this gives some information on allocated memory, time spend, and so on. */
638 #include <sys/time.h>
639 #include <sys/resource.h>
640 struct rusage rusage
;
642 extern long mbkalloc_stat
;
646 pagesize
= getpagesize() / 1024;
647 (void)getrusage(RUSAGE_SELF
, &rusage
);
648 (void)fprintf(stdout
, "mbk stats : %d call\n", ++times
);
649 (void)fprintf(stdout
, "user time : %ld sec\n",
650 rusage
.ru_utime
.tv_sec
);
651 (void)fprintf(stdout
, "system time : %d sec\n",
652 rusage
.ru_stime
.tv_usec
);
653 (void)fprintf(stdout
, "real size : %ld k\n",
654 rusage
.ru_maxrss
* pagesize
);
655 (void)fprintf(stdout
, "mbkalloc peak size : %ld k\n",
656 mbkalloc_stat
/ 1024);
657 (void)fprintf(stdout
, "mallinfo size : %ld k\n",
658 mallinfo().arena
/ 1024);
662 /* mbkpopen : open a pipe with a filter, return a FILE*
666 FILE* mbkpopen( char *nom
, char *filter
, char mode
)
678 O_WRONLY
|O_CREAT
|O_TRUNC
,
679 S_IRUSR
|S_IWUSR
|S_IRGRP
|S_IWGRP
|S_IROTH
|S_IWOTH
682 fic
= open( nom
, O_RDONLY
);
687 if( pipe( ptf
) == -1 )
690 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" )\n", nom
);
695 argv
= decompfilter( filter
);
701 perror( "vfork() " );
702 if( i
<VFORKMAXTRY
) {
704 printf( "vfork() #%d attempt failed. wait a few moment...\n", i
);
710 while( pid
== -1 && i
<= VFORKMAXTRY
);
715 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" )\n", nom
);
716 printf( "Memory usage : %ldKb\n", mbkprocessmemoryusage()/1024 );
727 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom
);
728 fprintf( stderr
, "Bad filter.\n" );
734 if( dup2( ptf
[0], 0 ) == -1 )
736 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom
);
737 perror( "dup2( ptf[0], 0 ) ");
741 if( dup2( fic
, 1 ) == -1 )
743 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom
);
744 perror( "dup2( fic, 1 ) ");
750 if( dup2( ptf
[1], 1 ) == -1 )
752 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom
);
753 perror( "dup2( ptf[1], 1 ) ");
757 if( dup2( fic
, 0 ) == -1 )
759 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom
);
760 perror( "dup2( fic, 0 ) ");
765 if( close( fic
) == -1 )
767 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom
);
768 perror( "close( fic ) ");
772 if( close( ptf
[1] ) == -1 )
774 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom
);
775 perror( "close( ptf[1] ) ");
779 if( close( ptf
[0] ) == -1 )
781 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom
);
782 perror( "close( ptf[0] ) ");
786 if( V_BOOL_TAB
[ __MBK_FILTER_MASK_ERROR
].VALUE
) {
787 errfile
= open( "/dev/null", 0 );
789 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom
);
790 perror( "open(\"/dev/null\",0) " );
793 if( dup2( errfile
, 2 ) == -1 )
795 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom
);
796 perror( "dup2( errfile, 2 ) ");
799 if( close( errfile
) == -1 )
801 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom
);
802 perror( "close( errfile ) ");
807 if( execvp( argv
[0], &(argv
[1]) ) == -1 )
809 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) child\n", nom
);
815 for( i
=0 ; argv
[i
] ; i
++ )
819 mbksetautoackchld( pid
);
824 if( close( ptf
[0] ) == -1 )
827 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) parent\n", nom
);
828 perror( "close( ptf[0] ) ");
832 file
= fdopen( ptf
[1], "w" );
836 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) parent\n", nom
);
837 perror( "fdopen( ptf[1], \"w\" ) ");
843 if( close( ptf
[1] ) == -1 )
846 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) parent\n", nom
);
847 perror( "close( ptf[1] ) ");
851 file
= fdopen( ptf
[0], "r" );
855 fprintf( stderr
, "*** Fatal error in mbkpopen( \"%s\" ) parent\n", nom
);
856 perror( "fdopen( ptf[0], \"r\" ) ");
864 char **decompfilter( char *filter
)
877 /* remove trailing space */
878 for( pos
= 0 ; filter
[pos
] == ' ' && filter
[pos
] != 0 ; pos
++ );
879 if( filter
[pos
] == 0 )
882 /* The full path to binairie */
883 for( i
= pos
; filter
[i
] != ' ' && filter
[i
] != 0 ; i
++ );
884 fullpath
= (char*)mbkalloc( sizeof(char) * ( i
-pos
+1 ) );
885 strncpy( fullpath
, filter
+pos
, i
-pos
);
889 /* The binairie himself */
890 pt
= strrchr( fullpath
, '/' );
891 argv0
= (char*)mbkalloc( sizeof( char ) * (strlen( fullpath
) + 1) );
893 strcpy( argv0
, fullpath
);
895 strcpy( argv0
, pt
+sizeof(char) );
903 for( ; filter
[pos
] == ' ' && filter
[pos
] != 0 ; pos
++ );
904 if( filter
[pos
] == 0 )
907 for( i
= pos
; filter
[i
] != ' ' && filter
[i
] != 0 ; i
++ );
908 argvn
= (char*)mbkalloc( sizeof( char ) * ( i
-pos
+1 ) );
909 strncpy( argvn
, filter
+pos
, i
-pos
);
912 head
= addchain( head
, argvn
);
917 head
= reverse( head
);
919 ret
= (char**)mbkalloc( sizeof(char*) * (nbarg
+1) );
924 for( scan
= head
, pos
=2 ; scan
; scan
= scan
->NEXT
, pos
++ )
925 ret
[pos
] = scan
->DATA
;
933 void mbkackchld( int sig
)
936 autoackchld_list
*scanauto
, *prevauto
, *nextauto
;
938 /* Le handlert d'interruption SIGCHLD. Il doit avoir été configuré pour ne
939 * pas être interrompu par lui même. */
945 "*** mbk warning : call of mbkackchld with signal %d\n",
951 for( scanauto
= HEAD_AUTOACKCHLD
, prevauto
=NULL
;
956 nextauto
= scanauto
->NEXT
;
957 if( waitpid(scanauto
->PID
, &status
, WNOHANG
) == scanauto
->PID
)
960 prevauto
->NEXT
= scanauto
->NEXT
;
962 HEAD_AUTOACKCHLD
= scanauto
->NEXT
;
963 mbkfreeautoackchld( scanauto
);
965 else prevauto
= scanauto
;
969 autoackchld_list
* mbkgetautoackchld( void )
971 autoackchld_list
*new;
973 if( ! HEAD_AUTOACKCHLD_FREE
)
977 "\n*** mbk ERROR : Not enought free slot in mbkgetautoackchld().\n"
982 new = HEAD_AUTOACKCHLD_FREE
;
983 HEAD_AUTOACKCHLD_FREE
= HEAD_AUTOACKCHLD_FREE
->NEXT
;
989 void mbkfreeautoackchld( autoackchld_list
*bloc
)
991 bloc
->NEXT
= HEAD_AUTOACKCHLD_FREE
;
992 HEAD_AUTOACKCHLD_FREE
= bloc
;
996 void mbkinitautoackchld( void )
998 autoackchld_list
*bloc
;
1001 bloc
=(autoackchld_list
*)mbkalloc( sizeof( autoackchld_list
) * ENDCHLD_MAX
);
1002 n
= AUTOACKCHLD_MAX
- 1;
1003 bloc
[n
].NEXT
= NULL
;
1007 bloc
[n
].NEXT
= &( bloc
[n
+1] );
1009 HEAD_AUTOACKCHLD_FREE
= &(bloc
[0]);
1013 void mbksetautoackchld( int pid
)
1015 autoackchld_list
*new;
1019 /* Fonction utilisateur : on met dans la liste HEAD_AUTOACKCHLD un numéro de
1020 * pid. Dès qu'un processus fils se termine ave ce pid, il sera
1021 * automatiquement supprimé. */
1023 /* Dans le déroulement normal du programme, on touche ici à des structures
1024 * qui sont modifiées par le handler SIGCHLD. On évite de mettre le bazard en
1025 * blindant le morceau de code. */
1027 sigemptyset( &set
);
1028 sigaddset( &set
, SIGCHLD
);
1029 sigprocmask( SIG_BLOCK
, &set
, NULL
);
1031 if( waitpid( pid
, &status
, WNOHANG
) == 0 ) /* pas deja termine */
1033 /* On ne voudra jamais savoir ce qu'est devenu le processus fils pid. On le
1034 * met dans la liste des processus à acquiter automatiquement */
1035 new = mbkgetautoackchld();
1037 new->NEXT
= HEAD_AUTOACKCHLD
;
1038 HEAD_AUTOACKCHLD
= new ;
1040 sigprocmask( SIG_UNBLOCK
, &set
, NULL
);
1043 unsigned long mbkprocessmemoryusage()
1052 sprintf(temp
,"/proc/%d/stat",pid
);
1053 if ((f
=fopen(temp
,"rt"))==NULL
) return (unsigned long)sbrk(0);
1054 for (cnt
=1;cnt
<=23;cnt
++) fscanf(f
,"%s",temp
);
1055 size
=strtoul(temp
,NULL
,10);
1061 unsigned long total
;
1065 sprintf( file
, "/proc/%d/as", (int)getpid());
1066 f
= open( file
, O_RDONLY
);
1067 if( f
< 0 ) return (unsigned long)sbrk(0);
1069 total
= (unsigned long )lseek( f
, 0, SEEK_END
);
1076 struct task_basic_info t_info
;
1077 mach_msg_type_number_t t_info_count
= TASK_BASIC_INFO_COUNT
;
1078 task_t task
= MACH_PORT_NULL
;
1080 if (task_for_pid(current_task(), getpid(), &task
) == KERN_SUCCESS
) {
1081 task_info(task
, TASK_BASIC_INFO
, (task_info_t
)&t_info
, &t_info_count
);
1082 return (unsigned long)(t_info
.virtual_size
- SHARED_TEXT_REGION_SIZE
- SHARED_DATA_REGION_SIZE
);
1088 char *mbkIsLofigExt(char *filename
, char *ext
)
1091 c
=&filename
[strlen(filename
)-1];
1092 while (c
!=filename
&& *c
!='.') c
--;
1093 if (c
==filename
) return NULL
;
1094 if (strcmp(c
+1,ext
)==0) return c
;
1095 if (FILTER_SFX
!=NULL
)
1099 while (c
!=filename
&& *c
!='.') c
--;
1100 if (c
==filename
) return NULL
;
1101 sprintf(temp
,".%s%s",ext
,FILTER_SFX
);
1102 if (strcmp(c
,temp
)==0) return c
;
1108 static char *ext
[]={"","","","al","spi","hns","fdn","vhd","vlg","v","vst"};
1110 static void setext()
1115 char *SPI_SFX
="spi", *VHD_SFX
="vhd", *VLG_SFX
="vlg";
1116 if ((c
=V_STR_TAB
[__MBK_SPI_SUFFIX
].VALUE
)!=NULL
) SPI_SFX
=c
;
1117 if ((c
=V_STR_TAB
[__MVL_FILE_SUFFIX
].VALUE
)!=NULL
) VHD_SFX
=c
;
1118 if ((c
=V_STR_TAB
[__MGL_FILE_SUFFIX
].VALUE
)!=NULL
) VLG_SFX
=c
;
1126 char *mbkFileIsLofig(char *filename
)
1131 for (i
=0;i
<sizeof(ext
)/sizeof(*ext
); i
++)
1132 if ((c
=mbkIsLofigExt(filename
, ext
[i
]))!=NULL
) return c
;
1137 /****************************************************************************/
1138 /*{{{ Pipe functions */
1140 /* author : Antony PinTo (anto) */
1142 /* 8 january 2004 : anto creation */
1144 /****************************************************************************/
1145 /*{{{ mbkpprint() */
1147 /* write into a pipe */
1149 /****************************************************************************/
1150 int mbkpprint(int fildes
, void *data
, int size
)
1152 ssize_t writen
, remaining
;
1154 remaining
= (ssize_t
)size
;
1159 writen
+= write(fildes
,(char*)data
+writen
,remaining
);
1162 remaining
= size
- writen
;
1165 return (writen
== (ssize_t
)size
);
1168 /*}}}************************************************************************/
1173 /****************************************************************************/
1174 int mbkpscan(int fildes
, void *data
, int size
)
1176 ssize_t readen
, remaining
, this_time
;
1178 remaining
= (ssize_t
)size
;
1183 this_time
= read(fildes
,(char*)data
+readen
,remaining
);
1184 readen
+= this_time
;
1187 remaining
= size
- readen
;
1190 return (readen
== (ssize_t
)size
);
1193 /*}}}************************************************************************/
1194 /*{{{ mbkpcreate() */
1196 /* forks and create the communication pipes */
1198 /* return the result of fork() */
1200 /****************************************************************************/
1201 pid_t
mbkpcreate(int *file_des_write
, int *file_des_read
)
1204 int server_to_client
[2];
1205 int client_to_server
[2];
1207 pipe(server_to_client
);
1208 pipe(client_to_server
);
1210 switch ((son_id
= fork()))
1213 *file_des_write
= 0;
1216 case 0 : // son is the client
1217 *file_des_write
= client_to_server
[1];
1218 *file_des_read
= server_to_client
[0];
1220 default : // father is the server
1221 *file_des_write
= server_to_client
[1];
1222 *file_des_read
= client_to_server
[0];
1229 /*}}}************************************************************************/
1230 /*}}}************************************************************************/
1231 /*{{{ Test if come from gdb */
1232 /****************************************************************************/
1236 /****************************************************************************/
1238 int isGdb(char *name
)
1240 return !strncmp("gdb",name
,3);
1243 /*}}}************************************************************************/
1244 /*{{{ mbk_whoAmI() */
1246 /* fill the buffer name with the process name */
1248 /****************************************************************************/
1250 char *mbk_whoAmI(pid_t pd
, char *name
)
1260 sprintf(buf
,"/proc/%d/stat",(int)pd
);
1262 if ((fd
= open(buf
,O_RDONLY
)) >= 0)
1264 len
= read(fd
, buf
, sizeof(buf
)-1);
1267 p
= strchr(p
,'(')+1;
1270 if (len
>= (signed)sizeof(name
))
1271 len
= sizeof(name
)-1;
1282 char *mbk_whoAmI(pid_t pd
, char *name
)
1293 sprintf(buf
,"/proc/%d/psinfo",(int)pd
);
1295 if ((fd
= open(buf
,O_RDONLY
)) >= 0)
1297 if ((read(fd
,&curproc
,sizeof(psinfo_t
))) == sizeof(psinfo_t
))
1299 p
= curproc
.pr_fname
;
1312 char *mbk_whoAmI(pid_t pd
, char *name
)
1315 size_t len
= sizeof(struct kinfo_proc
);
1316 struct kinfo_proc kp
;
1320 mib
[2] = KERN_PROC_PID
;
1322 if (sysctl(mib
, 4, &kp
, &len
, NULL
, 0) == 0) {
1323 strcpy(name
, kp
.kp_proc
.p_comm
);
1325 else strcpy(name
, "unknown");
1332 char *mbk_whoAmI(pid_t pd
, char *name
)
1335 strcpy(name
, "unknown");
1341 /*}}}************************************************************************/
1342 /*{{{ mbk_whoAmILong() */
1344 /* fill the buffer name with the process name */
1346 /****************************************************************************/
1348 char *mbk_whoAmILong(pid_t pd
, char *name
)
1358 sprintf(buf
,"/proc/%d/exe",(int)pd
);
1359 len
= readlink(buf
,buf2
,sizeof(buf
));
1362 sprintf(buf
,"/proc/%d/cmdline",(int)pd
);
1363 if ((fd
= open(buf
,O_RDONLY
)) >= 0)
1366 len
= read(fd
, buf
, sizeof(buf
)-1);
1367 for (i
= 0; i
< len
; i
++)
1377 sprintf(name
,"%s %s",buf2
,buf
+ done
+ 1);
1384 char *mbk_whoAmILong(pid_t pd
, char *name
)
1390 char *p
, *env
, *tt
, *strtok
;
1396 sprintf(buf
,"/proc/%d/psinfo",(int)pd
);
1397 if ((fd
= open(buf
,O_RDONLY
)) >= 0)
1400 if ((read(fd
,&curproc
,sizeof(psinfo_t
))) == sizeof(psinfo_t
))
1402 p
= curproc
.pr_psargs
;
1404 if ((env
= getenv("PATH")))
1407 strtok
= strtok_r(env
,":",&tt
);
1409 sprintf(name
,"%s/%s",strtok
,curproc
.pr_fname
);
1410 if (!stat(name
,&st
) && (st
.st_mode
& (S_IROTH
| S_IXOTH
)))
1412 sprintf(name
,"%s/%s",strtok
,curproc
.pr_psargs
);
1438 char *mbk_whoAmILong(pid_t pd
, char *name
)
1441 size_t len
= sizeof(struct kinfo_proc
);
1442 struct kinfo_proc kp
;
1446 mib
[2] = KERN_PROC_PID
;
1448 if (sysctl(mib
, 4, &kp
, &len
, NULL
, 0) == 0) {
1449 strcpy(name
, kp
.kp_proc
.p_comm
);
1451 else strcpy(name
, "unknown");
1458 char *mbk_whoAmILong(pid_t pd
, char *name
)
1461 strcpy(name
, "unknown");
1466 /*}}}************************************************************************/
1467 /*}}}************************************************************************/
1469 chain_list
*BuildFileList(char *name
, chain_list
*regx
, int once
)
1473 char buf
[1024], *regxname
, buf0
[1024];
1476 chain_list
*cl
= NULL
, *ch
, *oncelist
=NULL
;
1477 /* regex_t regular_expression;
1478 regmatch_t pmatch[1];*/
1480 char *mycatal
[]={"", NULL
};
1484 save_sensi
=CASE_SENSITIVE
;
1490 regxname
=(char *)regx
->DATA
;
1494 for (i
=0; regxname
[i
]!='\0'; i
++)
1497 if (regxname
[i
]=='$') strcat(buf
, name
);
1498 else strcat(buf
, str
);
1502 strcpy(buf
, regxname
);
1504 if ((regxname
=strrchr(buf
, '/'))==NULL
)
1517 for (i
=0; catal
[i
]!=NULL
; i
++)
1519 dp
= opendir(catal
[i
]);
1522 while ((ep
= readdir(dp
)) != NULL
)
1524 if (mbk_TestREGEX(ep
->d_name
, regxname
))
1528 for (ch
=oncelist
; ch
!=NULL
&& strcmp((char *)ch
->DATA
, ep
->d_name
)!=0; ch
=ch
->NEXT
) ;
1529 if (ch
!=NULL
) continue;
1531 sprintf(buf0
, "%s/%s",catal
[i
],ep
->d_name
);
1533 if (stat(buf0
, &st
)!=ENOENT
&& !S_ISDIR(st
.st_mode
))
1535 for (ch
=cl
; ch
!=NULL
&& strcmp((char *)ch
->DATA
, buf0
)!=0; ch
=ch
->NEXT
);
1538 cl
=addchain(cl
, mbkstrdup(buf0
));
1539 if (once
) oncelist
=addchain(oncelist
, mbkstrdup(ep
->d_name
));
1550 CASE_SENSITIVE
=save_sensi
;
1552 for (ch
=oncelist
; ch
!=NULL
; ch
=ch
->NEXT
)
1554 freechain(oncelist
);
1559 #undef mbk_DisplayProgress
1561 void mbk_DisplayProgress(long *TM
, char *mes
, int cur
, int tot
, char mode
)
1565 if (!isatty (fileno(stdout
))) return;
1566 if (mode
=='e' || *TM
!=(tmp
=time(NULL
)))
1570 fprintf(stdout
, "\r%s[%3.2f%%]", mes
, (cur
*100.0)/tot
);
1572 fprintf(stdout
, "\r%s[%07d/%07d]", mes
, cur
, tot
);
1573 if (mode
=='e') fprintf(stdout
, "\n");
1578 void mbk_sem_init(mbk_sem_t
*sm
, int value
)
1581 pthread_mutex_init(&sm
->mutex
, NULL
);
1582 pthread_cond_init(&sm
->cond
, NULL
);
1585 void mbk_sem_destroy(mbk_sem_t
*sm
)
1587 pthread_mutex_destroy(&sm
->mutex
);
1588 pthread_cond_destroy(&sm
->cond
);
1591 void mbk_sem_wait(mbk_sem_t
*sm
)
1594 pthread_mutex_lock(&sm
->mutex
);
1595 while (sm
->nb
<=0) pthread_cond_wait(&sm
->cond
, &sm
->mutex
);
1597 pthread_mutex_unlock(&sm
->mutex
);
1600 void mbk_sem_post(mbk_sem_t
*sm
)
1602 pthread_mutex_lock(&sm
->mutex
);
1604 pthread_mutex_unlock(&sm
->mutex
);
1605 pthread_cond_signal(&sm
->cond
);