"Fossies" - the Fresh Open Source Software Archive

Member "delegate9.9.13/rary/ystring.c" (13 Jun 2010, 46364 Bytes) of package /linux/misc/old/delegate9.9.13.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ystring.c" see the Fossies "Dox" file reference documentation.

    1 /*////////////////////////////////////////////////////////////////////////
    2 Copyright (c) 2004-2008 National Institute of Advanced Industrial Science and Technology (AIST)
    3 AIST-Product-ID: 2000-ETL-198715-01, H14PRO-049, H15PRO-165, H18PRO-443
    4 
    5 Permission to use this material for noncommercial and/or evaluation
    6 purpose, copy this material for your own use, and distribute the copies
    7 via publicly accessible on-line media, without fee, is hereby granted
    8 provided that the above copyright notice and this permission notice
    9 appear in all copies.
   10 AIST MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY OF THIS
   11 MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS", WITHOUT ANY EXPRESS
   12 OR IMPLIED WARRANTIES.
   13 /////////////////////////////////////////////////////////////////////////
   14 Content-Type:   program/C; charset=US-ASCII
   15 Program:    ystring.c (boundary checkiing string manipulation)
   16 Author:     Yutaka Sato <ysato@delegate.org>
   17 Description:
   18 History:
   19     041107  created
   20 
   21 TODO:
   22     strlen() should not be used to avoid read-overrun
   23 //////////////////////////////////////////////////////////////////////#*/
   24 #include <stdlib.h>
   25 #include <string.h>
   26 #include <stdio.h>
   27 #include <errno.h>
   28 
   29 #if defined(_MSC_VER) && defined(UNDER_CE)
   30 static int Igetc(FILE *fp){ return getc(fp); }
   31 char *strdup(const char*);
   32 FILE *fdopen(int,const char*);
   33 #endif
   34 
   35 const char *MyVer = "";
   36 
   37 #if defined(FMT_CHECK) /*{*/
   38 #define daemonlog(wh,fmt,...)  fprintf(stderr,fmt,##__VA_ARGS__)
   39 #define porting_dbg(fmt,...)   fprintf(stderr,fmt,##__VA_ARGS__)
   40 #else
   41 int daemonlog(const char *what,const char *fmt,...);
   42 int porting_dbg(const char *fmt,...);
   43 #endif
   44 
   45 void Abort(int code,const char *fmt,...);
   46 int numthreads();
   47 int actthreads();
   48 
   49 char *Xstrdup(const char *F,int L,int pstm,const char *s){
   50     char *mp;
   51     mp = strdup(s);
   52     if( mp == NULL ){
   53         Abort(0,"FAILED strdup(%X) %s:%d\n",s,F,L);
   54     }
   55     else{
   56     }
   57     return mp;
   58 }
   59 
   60 /*
   61  * mutex and memory leak detection for heap area
   62  */
   63 typedef struct {
   64     const char *a_F; /* source-file of the allocator */
   65     short   a_L;    /* source-line of the allocator */
   66     char    a_free; /* flags */
   67     char    a_base; /* is stack-base */
   68     int a_z;    /* size of the area */
   69     void   *a_p;    /* the address of the allocated memory */
   70 } Alloc;
   71 
   72 static Alloc persistents[1024];
   73 static Alloc allocs[1024];
   74 static int allocsp;
   75 static int lastpopend;
   76 
   77 typedef struct {
   78     int  l_lid;
   79     int  l_tid;
   80     int  l_dbg;
   81     char l_lev;
   82  const char *l_wh;
   83  const char *l_F;
   84     int  l_L;
   85       double l_Time;
   86 } Lock;
   87 static Lock curLock;
   88 static Lock noLock;
   89 static Lock doLock_FL(const char *F,int L,const char *wh,int log);
   90 static void unLock_FL(const char *F,int L,const char *wh,int log,Lock locked);
   91 
   92 #ifdef __FUNCTION__
   93 #define _WHERE_ __FUNCTION__
   94 #else
   95 #define _WHERE_ __FILE__
   96 #endif
   97 #define doLock(wh,log) locked = doLock_FL(_WHERE_,__LINE__,wh,log)
   98 #define unLock(wh,log) unLock_FL(_WHERE_,__LINE__,wh,log,locked)
   99 #define doLockB(wh,log) locked = doLock_FL(FL_Bar,wh,log)
  100 #define unLockB(wh,log) unLock_FL(FL_Bar,wh,log,locked)
  101 
  102 /*
  103 #include <signal.h>
  104 */
  105 #include "vsignal.h"
  106 #include "ysignal.h"
  107 static struct {
  108     const char *h_W;
  109     const char *h_F;
  110     int h_L;
  111     int h_Z;
  112 } heapst = {"",""};
  113 void putfLog(const char *fmt,...);
  114 void msleep(int ms);
  115 static void sigSEGV(int sig){
  116     errno = ENOMEM;
  117     putfLog("####got sigSEGV");
  118     msleep(200);
  119     if( 0 <= heapst.h_Z )
  120         Abort(0,"FATAL %s(%d) %s:%d\n",
  121             heapst.h_W,heapst.h_Z,heapst.h_F,heapst.h_L);
  122     else    Abort(0,"FATAL %s() %s:%d\n",heapst.h_W,heapst.h_F,heapst.h_L);
  123 }
  124 typedef void (*sigfunc)(int);
  125 static sigfunc setsig(const char *W,const char *F,int L,int z){
  126     heapst.h_W = W;
  127     heapst.h_F = F;
  128     heapst.h_L = L;
  129     heapst.h_Z = z;
  130     return signal(SIGSEGV,sigSEGV);
  131 }
  132 int VStrSIG(){
  133     if( heapst.h_W && heapst.h_F ){
  134         putfLog("####lastSIG: %s[%d] <= %s:%d",
  135             heapst.h_W,heapst.h_Z,heapst.h_F,heapst.h_L);
  136         return 1;
  137     }
  138     return 0;
  139 }
  140 
  141 #define FL_Par const char *FL_F,int FL_L
  142 #define FL_Bar FL_F,FL_L
  143 void add_FILEY(FL_Par,const char *wh,FILE *fp);
  144 void del_FILEY(FL_Par,const char *wh,FILE *fp);
  145 
  146 /*
  147 #undef tmpfile
  148 FILE *Xtmpfile(FL_Par){
  149     FILE *fp;
  150     fp = tmpfile();
  151     if( fp ){
  152         add_FILEY(FL_Bar,"tmpfile",fp);
  153     }
  154     return fp;
  155 }
  156 */
  157 
  158 int p2iX(FL_PAR,const void *p);
  159 #define p2i(p) p2iX(FL_ARG,p)
  160 
  161 #if defined(_MSC_VER) && UNDER_CE
  162 #define isWindowsCE() 1
  163 #define isWindows() 1
  164 int XX_fflush_FL(const char *F,int L,FILE *fp);
  165 int XX_fclose_FL(const char *F,int L,FILE *fp);
  166 int XX_fcloseFILE_FL(const char *F,int L,FILE *fp);
  167 FILE *XX_fdopen_FL(const char *F,int L,int fd,const char *mode);
  168 FILE *XX_fopen_FL(const char *F,int L,const char *path,const char *mode);
  169 #define FL_fcloseFILE(F,L,fp) 0
  170 #else
  171 int FL_fcloseFILE(const char *F,int L,FILE *fp);
  172 #define isWindowsCE() 0
  173 #define XX_fgets(buf,siz,fp) 0
  174 #define XX_fflush_FL(FL_P,fp) 0
  175 #if defined(_MSC_VER)
  176 #define isWindows() 1
  177 int XX_fclose_FL(const char *F,int L,FILE *fp);
  178 #else
  179 #define isWindows() 0
  180 #define XX_fclose_FL(FL_P,fp) 0
  181 #endif
  182 #define XX_fcloseFILE_FL(FL_P,fp) 0
  183 #define XX_fdopen_FL(FL_P,fd,mode) 0
  184 #define XX_fopen_FL(FL_P,p,m) 0
  185 #endif
  186 
  187 /* may block seconds for linger. */
  188 /* fcloseFILE() under mutex + close() could be enough. */
  189 #undef fclose
  190 int XXfclose(FL_Par,FILE *fp){
  191     int rcode;
  192     sigfunc sig = setsig("Xfclose",FL_Bar,-1);
  193     Lock locked;
  194     SSigMask sMask; setSSigMask(sMask);
  195     doLockB("fclose",2);
  196     if( isWindows() ){
  197         rcode = XX_fclose_FL(FL_Bar,fp);
  198     }else
  199     rcode = fclose(fp);
  200     del_FILEY(FL_Bar,"fclose",fp);
  201     unLockB("fclose-done",2);
  202     resetSSigMask(sMask);
  203     signal(SIGSEGV,sig);
  204     return rcode;
  205 }
  206 #undef fcloseFILE
  207 int XXfcloseFILE(FL_Par,FILE *fp){
  208     int rcode;
  209     sigfunc sig = setsig("XfcloseFILE",FL_Bar,-1);
  210     Lock locked;
  211     SSigMask sMask; setSSigMask(sMask);
  212     doLockB("fcloseFILE",2);
  213     if( isWindowsCE() ){
  214     rcode = XX_fcloseFILE_FL(FL_Bar,fp);
  215     }else{
  216     rcode = FL_fcloseFILE(FL_Bar,fp);
  217     }
  218     del_FILEY(FL_Bar,"fcloseFILE",fp);
  219     unLockB("fcloseFILE-done",2);
  220     resetSSigMask(sMask);
  221     signal(SIGSEGV,sig);
  222     return rcode;
  223 }
  224 #undef fdopen
  225 int getthreadid();
  226 FILE *XXfdopen(FL_Par,int fd,const char *mode){
  227     FILE *fp;
  228     sigfunc sig = setsig("Xdopen",FL_Bar,-1);
  229     Lock locked;
  230     SSigMask sMask; setSSigMask(sMask);
  231     doLockB("fdopen",2);
  232     if( isWindowsCE() ){
  233         fp = XX_fdopen_FL(FL_Bar,fd,mode);
  234         if( fp ){
  235 int nfd;
  236 nfd = (int)fileno(fp);
  237 if( fd != nfd ){
  238 fprintf(stderr,"-- %X fdopen %d -> %d/%d/%X <= %s:%d --------------------\n",
  239 0xFFF&getthreadid(),fd,nfd,fileno(fp),p2i(fp),FL_Bar);
  240 }
  241         }
  242     }else
  243     {
  244     fp = fdopen(fd,mode);
  245     }
  246     /*
  247     if( fp && numthreads() ){
  248         setvbuf(fp,0,_IOFBF,1024);
  249     }
  250     */
  251     add_FILEY(FL_Bar,"fdopen",fp);
  252     unLockB("fdopen-done",2);
  253     resetSSigMask(sMask);
  254     signal(SIGSEGV,sig);
  255     return fp;
  256 }
  257 #undef fopen
  258 #if isWindows()
  259 FILE *wfopenX(const char *path,const char *mode);
  260 #else
  261 #define wfopenX(path,mode) 0
  262 #endif
  263 FILE *XXfopen(FL_Par,const char *path,const char *mode){
  264     FILE *fp;
  265     Lock locked;
  266     SSigMask sMask; setSSigMask(sMask);
  267     doLockB("fopen",2);
  268     if( isWindowsCE() ){
  269         fp = XX_fopen_FL(FL_Bar,path,mode);
  270     }else{
  271         fp = fopen(path,mode);
  272         if( fp == NULL && isWindows() ){
  273             fp = wfopenX(path,mode);
  274         }
  275     }
  276     /*
  277     if( fp && numthreads() ){
  278         setvbuf(fp,0,_IOFBF,1024);
  279     }
  280     */
  281     add_FILEY(FL_Bar,"fopen",fp);
  282     unLockB("fopen-done",2);
  283     resetSSigMask(sMask);
  284     return fp;
  285 }
  286 
  287 #if defined(_MSC_VER) && defined(UNDER_CE)
  288 int Xfileno(FILE *fp);
  289 #undef fileno
  290 #define fileno(f) Xfileno(f)
  291 #endif
  292 int pop_fd(int fd,int rw);
  293 int fpop_fd(FILE *fp){
  294     if( feof(fp) ){
  295         if( 0 <= pop_fd(fileno(fp),0) ){
  296             daemonlog("E","fpop_fd(%d)\n",fileno(fp));
  297             clearerr(fp);
  298             return 1;
  299         }
  300     }
  301     return 0;
  302 }
  303 
  304 #undef p2i
  305 #undef daemonlog
  306 
  307 #include "ystring.h"
  308 #include "log.h"
  309 #ifndef EMU_NO_VSNPRINTF
  310 #define EMU_NO_VSNPRINTF lNO_VSNPRINTF()
  311 #endif
  312 
  313 #define HeapDebug lMALLOC()
  314 #define HEAPCHK (1<HeapDebug)
  315 #define HEAPDBG HeapDebug<4?0:fprintf
  316 #define HEAPVRB HeapDebug!=3?0:fprintf
  317 #define HEAPTRC HeapDebug<2?0:fprintf
  318 #define HEAPERR HeapDebug<1?0:fprintf
  319 
  320 
  321 #if defined(QSC)
  322 #define dSIZE VStrSIZE(d)
  323 #define dTAIL &dBASE[VStrSIZE(d)-1]
  324 #define AdTAIL dBASE,VStrSIZQ(d)
  325 #else
  326 #if !defined(QSS)
  327 #define dTAIL &dBASE[dSIZE-1]
  328 #define AdTAIL dBASE,dSIZE
  329 #else
  330 #define dBASE d
  331 #endif
  332 #endif
  333 
  334 #undef memmove
  335 #undef strncpy
  336 #undef sprintf
  337 #undef scanf
  338 
  339 SStr(VStrUNKNOWN,1);
  340 
  341 int FMT_XRsprintf(PRVStr(d),PCStr(f),...){
  342     int n;
  343     VARGS(16,f);
  344 
  345     n = Xsprintf(UVStr(d)*d,f,VA16);
  346     if( 0 < n ){
  347         *d += strlen(*d);
  348     }
  349     return n;
  350 }
  351 int strRL(const char **d){
  352     int len = strlen(*d);
  353     *d += len;
  354     return len;
  355 }
  356 
  357 /* 9.9.4 MTSS setSSigMask/resetSSigMask -Ets (-Dts)
  358  * suppressing signals that may cause freezing or "spin_lock" in mutex
  359  * (for flockfile, malloc, etc. and CSC) which are activated after a
  360  * thread is created.
  361  */
  362 int cnt_SSigMask;
  363 int pnumthreads();
  364 int set_SSigMask(SSigMask *sMask,int force){
  365     int nmask;
  366 
  367     sMask->s_set = 0;
  368     if( lMTSS_NOSSIG() ){ /* MTSS disabled safe-signal "-Dts" */
  369         return -1;
  370     }
  371     if( force
  372      || pnumthreads()
  373      || !isWindowsCE() && numthreads()
  374     ){
  375         cnt_SSigMask++;
  376         nmask = sigmask(SIGTERM)|sigmask(SIGINT)|sigmask(SIGPIPE);
  377         nmask |= sigmask(SIGHUP); /* for SIGHUP to Sticky */
  378         sMask->s_mask = sigblock(nmask);
  379         sMask->s_set = 1;
  380         return 0;
  381     }
  382     return -1;
  383 }
  384 int reset_SSigMask(SSigMask *sMask){
  385     if( sMask->s_set ){
  386         sMask->s_set = 0;
  387         sigsetmask(sMask->s_mask);
  388         return 0;
  389     }
  390     return -1;
  391 }
  392 static const char *litoa(int base,PVStr(buf),FileSize ival,int bytes,int wd){
  393     refQStr(bp,buf);
  394     char iv[32];
  395     int len;
  396     int v1;
  397     int cha;
  398     int neg = 0;
  399     int bits,obits;
  400 
  401     if( ival < 0 ){
  402         if( base == 10 ){
  403             setVStrPtrInc(bp,'-');
  404             neg = 1;
  405             ival = -ival;
  406         }
  407     }
  408     bits = bytes * 8;
  409     obits = 0;
  410     for( len = 0; len < elnumof(iv); ){
  411         if( base == 8 ){
  412             iv[len++] = ival & 0x7;
  413             if( (ival = ival >> 3) == 0 )
  414                 break;
  415             if( bits <= (obits += 3) )
  416                 break;
  417         }else
  418         if( base == 16 ){
  419             iv[len++] = ival & 0xF;
  420             if( (ival = ival >> 4) == 0 )
  421                 break;
  422             if( bits <= (obits += 4) )
  423                 break;
  424         }else{
  425             iv[len++] = ival % base;
  426             if( (ival = ival / base) == 0 )
  427                 break;
  428         }
  429     }
  430     if( len < wd ){
  431         int wi;
  432         if( neg ) wd--;
  433         for( wi = 0; wi < (wd-len); wi++ ){
  434             setVStrPtrInc(bp,'0');
  435         }
  436     }
  437     for( len--; 0 <= len; len-- ){
  438         v1 = 0xF & iv[len];
  439         if( v1 < 10 )
  440             cha = '0' + v1;
  441         else    cha = 'A' + v1-10;
  442         setVStrPtrInc(bp,cha);
  443     }
  444     setVStrEnd(bp,0);
  445     return bp;
  446 }
  447 int sputf(PVStr(msg),PCStr(fmt),...){
  448     refQStr(mp,msg);
  449     const char *fp;
  450     int fc;
  451     int ai = 0;
  452     int ib;
  453     int zp;
  454     int wd;
  455     FileSize iv;
  456     int with_ll = 0;
  457     VARGS(16,fmt);
  458 
  459     for( fp = fmt; fc = *fp; fp++ ){
  460         if( fc != '%' ){
  461             setVStrPtrInc(mp,fc);
  462             continue;
  463         }
  464         zp = 0;
  465         if( fp[1] == '0' ){
  466             zp = 1;
  467             fp++;
  468         }
  469         wd = 0;
  470         while( '0' <= fp[1] && fp[1] <= '9' ){
  471             wd = wd * 10 + (fp[1] - '0');
  472             fp++;
  473         }
  474         iv = p2ll(va[ai]);
  475         ib = sizeof(int);
  476         if( with_ll == 0 ){
  477             iv &= 0xFFFFFFFF;
  478             if( fp[1] == 'd' ){
  479                 iv = (FileSize)(int)iv;
  480             }
  481         }
  482         switch( fp[1] ){
  483             case '%':
  484                 setVStrPtrInc(mp,fc);
  485                 fp++;
  486                 break;
  487             case 'x':
  488             case 'X':
  489                 mp = (char*)litoa(16,AVStr(mp),iv,ib,wd);
  490                 ai++;
  491                 fp++;
  492                 break;
  493             case 'u':
  494             case 'd':
  495                 mp = (char*)litoa(10,AVStr(mp),iv,ib,wd);
  496                 ai++;
  497                 fp++;
  498                 break;
  499             case 's':
  500                 strcpy(mp,va[ai]);
  501                 mp += strlen(mp);
  502                 ai++;
  503                 fp++;
  504                 break;
  505         }
  506     }
  507     setVStrEnd(mp,0);
  508     return mp - msg;
  509 }
  510 int curLogFd();
  511 int uGetpid();
  512 int GmtOff();
  513 int endthreads();
  514 
  515 int addCR(FILE *fp,int fd,PCStr(str)){
  516     if( lCONSOLE() ){
  517         if( strchr(str,'\r') == 0 )
  518         if( isatty(fd) ){
  519             /* if( isnotcooked(fd) ) */
  520             if( fp ){
  521                 fputc('\r',fp);
  522             }else{
  523                 write(fd,"\r",1);
  524             }
  525         }
  526     }
  527     return 0;
  528 }
  529 void FMT_putfLog(PCStr(fmt),...){
  530     IStr(msg,256);
  531     refQStr(mp,msg);
  532     int now;
  533     int pid;
  534     int upid;
  535     int efd;
  536     VARGS(16,fmt);
  537 
  538     if( curLogFd() < 0 ){
  539         return;
  540     }
  541     now = time(0) + GmtOff();
  542     mp += sputf(AVStr(mp),"%02d:%02d:%02d",(now/3600)%24,(now/60)%60,now%60);
  543     pid = getpid();
  544     upid = uGetpid();
  545     if( pid != upid )
  546         mp += sputf(AVStr(mp),"[%d][%d][%d]%X ",pid,upid,getppid(),TID);
  547     else    mp += sputf(AVStr(mp),"[%d][%d]%X ",upid,pid,TID);
  548     mp += sputf(AVStr(mp),"%d/%d/%d/%d ",newthreads(),actthreads(),
  549         endthreads(),numthreads());
  550     sputf(AVStr(mp),fmt,VA16);
  551     strcat(mp,"\n");
  552 
  553     IGNRETP write(curLogFd(),msg,strlen(msg));
  554     if( lCONSOLE() && curLogFd() != (efd = fileno(stderr)) ){
  555         IGNRETP write(efd,msg,strlen(msg));
  556         addCR(0,efd,msg);
  557     }
  558 }
  559 
  560 extern const char *FL_F_Xfputs;  extern int FL_L_Xfputs, inXfputs;
  561 extern const char *FL_F_Xfwrite; extern int FL_L_Xfwrite,inXfwrite;
  562 extern const char *FL_F_Xfflush; extern int FL_L_Xfflush,inXfflush;
  563 extern const char *FL_F_Xfclose; extern int FL_L_Xfclose,inXfclose;
  564 extern const char *FL_F_Malloc;  extern int FL_L_Malloc,inMalloc;
  565 extern const char *FL_F_Localtm; extern int FL_L_Localtm,inLocaltm;
  566 const char *FL_F_Gzip; int FL_L_Gzip,inGzip;
  567 
  568 int getXf_list(PVStr(Xf)){
  569     if( inXfputs || inXfwrite || inXfflush || inXfclose || inGzip ){
  570         if( inXfputs ){
  571             strcat(Xf,"Xfputs");
  572             if( FL_F_Xfputs )
  573             sputf(TVStr(Xf),"(%s:%d)",FL_F_Xfputs,FL_L_Xfputs);
  574         }
  575         if( inXfwrite ){
  576             strcat(Xf,"Xfwrite");
  577             if( FL_F_Xfwrite )
  578             sputf(TVStr(Xf),"(%s:%d)",FL_F_Xfwrite,FL_L_Xfwrite);
  579         }
  580         if( inXfflush ){
  581             strcat(Xf,"Xfflush");
  582             if( FL_F_Xfflush )
  583             sputf(TVStr(Xf),"(%s:%d)",FL_F_Xfflush,FL_L_Xfflush);
  584         }
  585         if( inXfclose ){
  586             strcat(Xf,"Xfclose");
  587             if( FL_F_Xfclose )
  588             sputf(TVStr(Xf),"(%s:%d)",FL_F_Xfclose,FL_L_Xfclose);
  589         }
  590         if( inLocaltm ){
  591             strcat(Xf,"Localtm");
  592             if( FL_F_Localtm )
  593             sputf(TVStr(Xf),"(%s:%d)",FL_F_Localtm,FL_L_Localtm);
  594         }
  595         if( inMalloc ){
  596             strcat(Xf,"Malloc");
  597             if( FL_F_Malloc )
  598             sputf(TVStr(Xf),"(%s:%d)",FL_F_Malloc,FL_L_Malloc);
  599         }
  600         if( inGzip ){
  601             strcat(Xf,"Gzip");
  602             if( FL_F_Gzip )
  603             sputf(TVStr(Xf),"(%s:%d)",FL_F_Gzip,FL_L_Gzip);
  604         }
  605         return 1;
  606     }else{
  607         return 0;
  608     }
  609 }
  610 void putsLogXf(PCStr(wh),int isig){
  611     const char *ssig = "";
  612     IStr(Xf,64);
  613 
  614     if( isig )
  615     if( getXf_list(AVStr(Xf)) ){
  616         switch( isig ){
  617             case SIGTERM: ssig = "TERM"; break;
  618             case SIGPIPE: ssig = "PIPE"; break;
  619             case SIGALRM: ssig = "ALRM"; break;
  620             case SIGINT:  ssig = "INT";  break;
  621             case SIGHUP:  ssig = "HUP";  break;
  622         }
  623         putfLog("%s got SIG%s/%d in %s",wh,ssig,isig,Xf);
  624     }
  625 }
  626 
  627 
  628 #if defined(WITH_QVSTR)
  629 
  630 #define DBG_INIT    1
  631 #define DBG_ABORT   2
  632 #define DBG_VERBOSE 4
  633 #define DBG_NOTIFY  8
  634 
  635 static int debug_flags;
  636 static int nov;
  637 static void setup_debug(){
  638     const char *env;
  639     if( (debug_flags & DBG_INIT) != 0 ){
  640         return;
  641     }
  642     debug_flags |= DBG_INIT;
  643     if( env = getenv("DEBUG_VSTR") ){
  644         if( strstr(env,"abort") )
  645             debug_flags |= DBG_ABORT;
  646         if( strstr(env,"notify") )
  647             debug_flags |= DBG_NOTIFY;
  648         if( strstr(env,"verb") )
  649             debug_flags |= DBG_VERBOSE;
  650     }
  651 /*
  652     if( debug_flags & DBG_VERBOSE )
  653         fprintf(stderr,"DEBUG_VSTR %X\n",debug_flags);
  654 */
  655 }
  656 void Xwhatis(PVStr(d)){
  657     const char *F = dFILE;
  658     int L = dLINE;
  659     const char *T = dTAIL;
  660     int z;
  661     if( T == 0 )
  662         z = 0;
  663     else    z = (char*)T - d + 1;
  664     fprintf(stderr,"#### %s:%d %X - %X - %X (%d/%d)\n",F,L,p2i(dBASE),p2i(d),p2i(T),z,ll2i(T-dBASE+1));
  665 }
  666 char *VStrId(PVStr(wh),PVStr(vs)){
  667 #if defined(QSC)
  668     snprintf((char*)wh,VStrSIZE(wh),"%s:%d",vsFILE,vsLINE);
  669 #else
  670     snprintf((char*)wh,whSIZE,"%s:%d",vsFILE,vsLINE);
  671 #endif
  672     return (char*)wh;
  673 }
  674 
  675 static void putvstr(char *dst,int siz,PVStr(d)){
  676     int di,ch;
  677     const char *dp;
  678     const char *vx;
  679     char *vp;
  680     vp = dst;
  681 
  682     *vp++ = '"';
  683     vx = &d[siz-1];
  684     /*
  685     if( dp == NULL ){
  686     bug from 9.0.6
  687     */
  688     if( d == NULL ){
  689         goto END;
  690     }
  691 
  692     for( di = 0; di < dSIZE && di < 32; di++ ){
  693         dp = &dBASE[di];
  694         ch = 0xFF & *dp;
  695         if( ch == 0 )
  696             goto END;
  697         if( 0x20 <= ch && ch < 0x7F && ch != '\\' )
  698             *vp++ = ch;
  699         else{
  700             snprintf(vp,vx-vp,"\\%02X",ch);
  701             vp += strlen(vp);
  702         }
  703     }
  704     dp = &d[di];
  705     if( dp < dTAIL-32 ){
  706         *vp++ = '"';
  707         snprintf(vp,vx-vp,"[%X]",p2i(dTAIL-32));
  708         vp += strlen(vp);
  709         *vp++ = '"';
  710     }
  711     for( dp = dTAIL-32; dp < dTAIL+16; dp++ ){
  712         ch = 0xFF & *dp;
  713         if( ch == 0 && d <= dp )
  714             break;
  715         if( 0x20 <= ch && ch < 0x7F && ch != '\\' )
  716             *vp++ = ch;
  717         else{
  718             snprintf(vp,vx-vp,"\\%02X",ch);
  719             vp += strlen(vp);
  720         }
  721         if( dp == dTAIL ){
  722             *vp++ = '"';
  723             *vp++ = '|';
  724             *vp++ = '"';
  725         }
  726     }
  727 END:
  728     *vp++ = '"';
  729     snprintf(vp,vx-vp,"[%X]",p2i(dp));
  730     vp += strlen(vp);
  731     *vp = 0;
  732 }
  733 void VStr_overflow(PCStr(where),PVStr(d),int len,int siz,PCStr(fmt),...){
  734     char msg[1024]; /**/
  735     char vstr[512];
  736     VARGS(16,fmt);
  737 
  738     snprintf(msg,sizeof(msg),
  739         "VStr overflow in %s (%s:%s:%d) %d/%d/%d %X-%X-%X ",
  740         where,MyVer,dFILE,dLINE,len,siz,dSIZE,p2i(dBASE),p2i(d),p2i(dTAIL));
  741     snprintf(msg+strlen(msg),sizeof(msg)-strlen(msg),fmt,VA16);
  742     putvstr(vstr,sizeof(vstr),BVStr(d));
  743     snprintf(msg+strlen(msg),sizeof(msg)-strlen(msg)," %s",vstr);
  744     if( lMULTIST() ){
  745         fprintf(stderr,"## [%X] %s\n",TID,msg);
  746     }else
  747     fprintf(stderr,"## [%d] %s\n",getpid(),msg);
  748     daemonlog("F","%s\n",msg);
  749 
  750     if( debug_flags & DBG_ABORT ){
  751 daemonlog("E","#### abort after 10 seconds...\n");
  752 sleep(10);
  753         abort();
  754     }
  755     nov++;
  756     if( 10 < nov )
  757         usleep(100);
  758 }
  759 #define Notify(v)   ((debug_flags&DBG_ABORT)?(abort(),v):v)
  760 
  761 const char *XcheckPtr(PVStr(d),const char *p){
  762     if( p < dBASE ){
  763         fprintf(stderr,"## POINTER UNDERFLOW %s:%d\n",dFILE,dLINE);
  764         VStr_overflow("XcheckPtr",BVStr(d),p-dBASE,dSIZE,"UNDERFLOW");
  765         abort();
  766     }
  767     if( dTAIL < p ){
  768         fprintf(stderr,"## POINTER OVERFLOW %s:%d\n",dFILE,dLINE);
  769         VStr_overflow("XcheckPtr",BVStr(d),p-dBASE,dSIZE,"OVERFLOW");
  770         abort();
  771     }
  772     return p;
  773 }
  774 
  775 int Xassert(PVStr(d),PCStr(p)){
  776     if( p < dBASE ){
  777         VStr_overflow("Xassert",dFILE,dLINE,AdTAIL,d,p-d,dTAIL-d,"");
  778         sleep(1);
  779         return -1;
  780     }
  781     if( dTAIL <= p ){
  782         VStr_overflow("Xassert",dFILE,dLINE,AdTAIL,d,p-d,dTAIL-d,"");
  783         sleep(1);
  784         return -1;
  785     }
  786     return 0;
  787 }
  788 static int outofrange(PCStr(wh),PVStr(d),int z){
  789     setup_debug();
  790     if( d < dBASE || dTAIL < d ){
  791         VStr_overflow(wh,dFILE,dLINE,AdTAIL,d,UTail(d)-d+1,0,
  792             "pointer out of range");
  793         return 1;
  794     }
  795     if( z )
  796     if( d+z < dBASE || dTAIL+1 < d+z ){
  797         VStr_overflow(wh,dFILE,dLINE,AdTAIL,d,UTail(d)-d+1,z,
  798             "index out of range");
  799         return 1;
  800     }
  801     return 0;
  802 }
  803 
  804 int XQVSSize(PVStr(d),int z){
  805     int rem;
  806     if( outofrange("XQVSSize",BVStr(d),z) ){
  807         return Notify(0);
  808     }
  809     rem = (dBASE+dSIZE) - d;
  810     if( rem < z ){
  811         VStr_overflow("XQVSSize",dFILE,dLINE,AdTAIL,d,z,rem,"");
  812         if( rem < 0 )
  813             z = 0;
  814         else    z = rem;
  815     }
  816     return z;
  817 }
  818 
  819 void *Xmemmove(PVStr(d),PCStr(s),int size){
  820     int z;
  821     if( outofrange("Xmemmove",BVStr(d),size) ){
  822         return Notify((char*)d);
  823     }
  824     if( dTAIL == 0 )
  825         z = 0;
  826     else    z = (char*)dTAIL - d + 1;
  827     if(dTAIL+1 < d+size){
  828         VStr_overflow("Xmemmove",dFILE,dLINE,AdTAIL,d,size,z,"");
  829         /*
  830         size = dTAIL+1-d;
  831         */
  832         size = dTAIL - d;
  833         if( size < 0 ){
  834             return (char*)d;
  835         }
  836     }
  837     return memmove((char*)d,s,size);
  838 }
  839 void Xbcopy(const void *s,PVStr(d),int z){
  840     if( outofrange("Xbcopy",BVStr(d),z) ){
  841         return;
  842     }
  843     if( dTAIL+1 < d+z ){
  844     VStr_overflow("Xbcopy",dFILE,dLINE,AdTAIL,d,UTail(d)-d+1,z,"");
  845         /*
  846         z = dTAIL - d + 1;
  847         */
  848         z = dTAIL - d;
  849     }
  850     /*
  851     source pointer "s" should be checked too, not to cause overrun.
  852      */
  853     bcopy(s,(char*)d,z);
  854 }
  855 char *XStrncpy(PVStr(d),PCStr(s),int z){
  856     char *dp = (char*)d;
  857     int n = z;
  858 
  859     if( outofrange("XStrncpy",BVStr(d),0) ){
  860         return Notify((char*)d);
  861     }
  862     if( dTAIL+1 < d+z ){
  863     VStr_overflow("XStrncpy",dFILE,dLINE,AdTAIL,d,UTail(d)-d+1,z,"");
  864         n = dTAIL - d + 1;
  865     }
  866     while( 1 < n-- ){
  867         if( (*dp++ = *s++) == 0 )
  868             break;
  869     }
  870     *dp = 0;
  871     return (char*)d;
  872 }
  873 char *Xstrncpy(PVStr(d),PCStr(s),int size){
  874     const char *F = dFILE;
  875     int L = dLINE;
  876     const char *T = dTAIL;
  877     int z;
  878 
  879     setup_debug();
  880     if( outofrange("Xstrncpy",BVStr(d),size) ){
  881         return Notify((char*)d);
  882     }
  883     if( T == 0 )
  884         z = 0;
  885     else    z = (char*)T - d + 1;
  886     if(z < size ){
  887         VStr_overflow("Xstrncpy",F,L,AdTAIL,d,size,z,"");
  888         size = z;
  889     }
  890     strncpy((char*)d,s,size);
  891     return (char*)d;
  892 }
  893 int XsetVStrEnd(PVStr(d),int x){
  894 /*
  895 fprintf(stderr,"######## TAIL dTAIL=%X UTAIL=%X toP=%X size=%X CUR %X\n",dTAIL,UTail(d),d,dSIZE,&d[x]);
  896 */
  897     if( dBASE == 0 && dSIZE == 0 ){
  898         VStr_overflow("XsetVStrEnd",dFILE,dLINE,AdTAIL,d,x,0,"");
  899         return Notify(0);
  900     }
  901     if( outofrange("XsetVStrEnd",BVStr(d),0) ){
  902         *(char*)dTAIL = 0;
  903         return Notify(0);
  904     }
  905     if( dTAIL < &d[x] ){
  906         VStr_overflow("XsetVStrEnd",dFILE,dLINE,AdTAIL,d,x,UTail(d)-d+1,"");
  907         *(char*)UTail(d) = 0;
  908         return UTail(d)-d;
  909     }else{
  910         ((char*)d)[x] = 0;
  911         return x;
  912     }
  913 }
  914 
  915 char *Xstrcpy(PVStr(d),PCStr(s)){
  916     const char *F = dFILE;
  917     int L = dLINE;
  918     const char *T = dTAIL;
  919     char *e; /**/
  920     int z;
  921     int l; /* source string length */
  922     int i;
  923 
  924     setup_debug();
  925     if( outofrange("Xstrcpy",BVStr(d),0) ){
  926         return Notify((char*)d);
  927     }
  928     if( T == 0 )
  929         z = 0;
  930     else    z = (char*)T - d + 1;
  931     l = strlen(s);
  932 
  933 /*
  934 fprintf(stderr,"##### U=%X T=%X d=%X B=%X Z=%X T=%X %X\n",
  935 VStrUNKNOWN,T,d,dBASE,dSIZE,dTAIL,T);
  936 */
  937     if(T != VStrUNKNOWN)
  938     if(T == 0 || z < l ){
  939         VStr_overflow("Xstrcpy",F,L,AdTAIL,d,l,z,"");
  940     }
  941 
  942  if( debug_flags & DBG_VERBOSE )
  943  fprintf(stderr,"## [%d] Xstrcpy (%s:%d) %3X/%5X %08X - %08X\n",
  944     getpid(),F,L, istrlen(s),z,p2i(d),p2i(s));
  945 
  946     e = (char*)d;
  947     for( i = 1; i < z; i++ ){
  948         if( (*e++ = *s++) == 0 ){
  949             break;
  950         }
  951     }
  952     if( i == z )
  953     *e = 0;
  954     return (char*)d;
  955 }
  956 char *Xstrcat(PVStr(d),PCStr(s)){
  957     const char *F = dFILE;
  958     int L = dLINE;
  959     const char *T = dTAIL;
  960     char *t; /**/
  961     int z;
  962 
  963     setup_debug();
  964     if( outofrange("Xstrcat",BVStr(d),0) ){
  965         return Notify((char*)d);
  966     }
  967     if( T == 0 )
  968         z = 0;
  969     else    z = (char*)T - d + 1;
  970 
  971  if( debug_flags & DBG_VERBOSE )
  972  fprintf(stderr,"## [%d] Xstcrat (%s:%d) %3X/%5X %08X - %08X)\n",
  973     getpid(),F,L, istrlen(s),z,p2i(d),p2i(s));
  974 
  975     for(t = (char*)d; *t; t++);
  976     Xstrcpy(F,L,AdTAIL,t,s);
  977     return (char*)d;
  978 }
  979 static void vfputs(PCStr(s),FILE *f){
  980     const char *p;
  981     int ch;
  982     for(p = s; ch = *p; p++){
  983         if( 0x20 <= ch && ch < 0x7F ){
  984             putc(ch,f);
  985         }else{
  986             putc('.',f);
  987         }
  988     }
  989 }
  990 
  991 static int floatFmt(PCStr(fmt));
  992 int FMT_Xsprintf(PVStr(d),PCStr(f),...){
  993     const char *F = dFILE;
  994     int L = dLINE;
  995     const char *T = dTAIL;
  996     int z,n;
  997     CStr(llfmt,1024);
  998 
  999 /*
 1000     static int N;
 1001     fprintf(stderr,"---- %4d %s:%d %s\n",++N,dFILE,dLINE,f);
 1002 */
 1003     setup_debug();
 1004     if( outofrange("Xsprintf",BVStr(d),0) ){
 1005         return Notify(0);
 1006     }
 1007     if( dTAIL == 0 )
 1008         z = 0;
 1009     else    z = (char*)T - d + 1;
 1010 
 1011 #ifndef NOVSNPRINTF
 1012  if( !EMU_NO_VSNPRINTF )
 1013  {
 1014     va_list nap;
 1015     va_start(nap,f);
 1016 
 1017     if( modifyFmt(f,AVStr(llfmt),sizeof(llfmt)) )
 1018         f = llfmt;
 1019 
 1020     if( numthreads() && floatFmt(f) ){
 1021         /* 9.9.4 MTSS to guard dtoa() for "%f" */
 1022         SSigMask sMask;
 1023         setSSigMask(sMask);
 1024         if( 0 < z )
 1025             n = vsnprintf((char*)d,z,f,nap);
 1026         else    n = vsnprintf((char*)d,0,f,nap);
 1027         resetSSigMask(sMask);
 1028     }else
 1029     if( 0 < z )
 1030         n = vsnprintf((char*)d,z,f,nap);
 1031     else    n = vsnprintf((char*)d,0,f,nap);
 1032     va_end(nap);
 1033  }
 1034  else
 1035 #endif
 1036  {
 1037     VARGS(16,f);
 1038 
 1039     if( modifyFmt(f,AVStr(llfmt),sizeof(llfmt)) )
 1040         f = llfmt;
 1041     if( 0 < z )
 1042         n = snprintf((char*)d,z,f,VA16);
 1043     else    n = snprintf((char*)d,0,f,VA16);
 1044  }
 1045 
 1046  if( debug_flags & DBG_VERBOSE ){
 1047  fprintf(stderr,"## [%d] Xsprintf (%s:%d) %3X/%5X",
 1048     getpid(),F,L, n,z);
 1049  vfputs(f,stderr);
 1050  fprintf(stderr,"\n");
 1051  }
 1052 
 1053     if( z == 0 || z <= n || n == -1 ){
 1054         VStr_overflow("Xsprintf",F,L,AdTAIL,d,n,z,"(%d) %s",strlen(d),f);
 1055     }
 1056 
 1057     return n;
 1058 }
 1059 
 1060 static int strlongereq(PCStr(str),int len){
 1061     int li;
 1062     const char *sp = str;
 1063     for( li = 0; li < len; li++ ){
 1064         if( *sp == 0 )
 1065             return 0;
 1066         sp++;
 1067     }
 1068     return 1;
 1069 }
 1070 int NO_ll_Fmt();
 1071 int Xsscanf(PCStr(str),PCStr(fmt),...){
 1072     const char *f;
 1073     int fc;
 1074     char xfmt[1024]; /**/
 1075     char *yfmt = xfmt;
 1076     char *x; /**/
 1077     const char *xp;
 1078     int ni = 0;
 1079     const char *F;
 1080     int L;
 1081     const char *T;
 1082 #if defined(QSC)
 1083     char *N; /**/
 1084 #endif
 1085     char *d; /**/
 1086     char *b; /**/
 1087     int z;
 1088     int xn;
 1089     int xi;
 1090     va_list ap;
 1091     char *va[16]; /**/
 1092     int len[16]; /**/
 1093     char *sa[16]; /* for safety in the case where length information */
 1094     char sc[16];  /* is longer than the real length */
 1095     int noverflow;
 1096     CStr(llfmt,1024);
 1097 
 1098     IStr(afmt,256);
 1099     if( NO_ll_Fmt() ){
 1100         if( modifyFmt(fmt,AVStr(afmt),sizeof(afmt)) ){
 1101             fmt = afmt;
 1102         }
 1103     }
 1104 
 1105     va_start(ap,fmt);
 1106     setup_debug();
 1107 
 1108     x = xfmt;
 1109     xp = &xfmt[sizeof(xfmt)-1];
 1110     for(f = fmt; fc = *f; f++){
 1111         if( xp <= x ){
 1112             break;
 1113         }
 1114         *x++ = fc;
 1115         if( fc != '%' )
 1116             continue;
 1117         if( elnumof(va) <= ni ){
 1118             fprintf(stderr,"## too many format specs: %s\n",fmt);
 1119             break;
 1120         }
 1121         fc = *++f;
 1122         *x++ = fc;
 1123         switch(fc){
 1124             case '%': continue;
 1125             case '*': continue;
 1126             case '0': case '1': case '2': case '3': case '4':
 1127             case '5': case '6': case '7': case '8': case '9':
 1128             case 'h': case 'l': case 'L': case 'j': case 't':
 1129             case 'z': case 'q':
 1130 
 1131             case 'd': case 'i': case 'o': case 'u':
 1132             case 'x': case 'X': case 'a': case 'A':
 1133             case 'e': case 'E': case 'f': case 'F':
 1134             case 'g': case 'G':
 1135             case 'c': case 'C':
 1136                 len[ni] = 0;
 1137                 va[ni++] = va_arg(ap,char*);
 1138                 break;
 1139             default:
 1140             fprintf(stderr,"## unknown format [%c]%s\n",fc,fmt);
 1141                 break;
 1142             case 's':
 1143             case '[':
 1144                 F = va_arg(ap,char*);
 1145                 L = va_arg(ap,int);
 1146 #if defined(QSC)
 1147                 b = va_arg(ap,char*);
 1148                 N = va_arg(ap,char*);
 1149                 z = N - b;
 1150                 T = &b[z-1];
 1151                 d = va_arg(ap,char*);
 1152                 z = T - d + 1;
 1153                 if( outofrange("Xsscanf",F,L,b,N,d,0) ){
 1154                     return Notify(0);
 1155                 }
 1156 #else
 1157 #if !defined(QSS)
 1158                 b = va_arg(ap,char*);
 1159                 z = va_arg(ap,int);
 1160                 T = &b[z-1];
 1161                 d = va_arg(ap,char*);
 1162                 z = T - d + 1;
 1163                 if( outofrange("Xsscanf",F,L,b,z,d,0) ){
 1164                     return Notify(0);
 1165                 }
 1166 #else
 1167                 T = va_arg(ap,char*);
 1168                 d = va_arg(ap,char*);
 1169                 z = T - d + 1;
 1170 #endif
 1171 #endif
 1172 
 1173  if(ni==0)
 1174  if( debug_flags & DBG_VERBOSE ){
 1175  fprintf(stderr,"## [%d] Xsscanf (%s:%d) ",getpid(),F,L);
 1176  vfputs(fmt,stderr);
 1177  fprintf(stderr,"\n");
 1178  }
 1179                 if( z <= 0 || 0x10000 < z ){
 1180                     z = 0;
 1181 fprintf(stderr,"## Xsscanf ## %d:%s size unknown [%c]%s[%d]\n",L,F,fc,fmt,ni);
 1182 sleep(2);
 1183                 }else{
 1184                     len[ni] = z;
 1185                     snprintf(x-1,8,"%d",z-1);
 1186 /* sscanf() on RedHat7.1 writes length=z+1(for  NUL) at overflow */
 1187 sa[ni] = &d[z-1];
 1188 sc[ni] = d[z-1];
 1189 d[z-1] = 0;
 1190                     x += strlen(x);
 1191                     *x++ = fc;
 1192                 }
 1193                 len[ni] = z;
 1194                 va[ni++] = d;
 1195                 break;
 1196         }
 1197     }
 1198     *x = 0;
 1199 
 1200     yfmt = xfmt;
 1201     if( modifyFmt(xfmt,AVStr(llfmt),sizeof(llfmt)) )
 1202     {
 1203         yfmt = llfmt;
 1204     }
 1205 
 1206     xn = sscanf(str,yfmt,va[0],va[1],va[2],va[3],va[4],va[5],va[6],va[7],va[8],va[9],va[10],va[11],va[12],va[13],va[14],va[15]);
 1207 
 1208     noverflow = 0;
 1209     for(xi = 0; xi < xn; xi++){
 1210         if(len[xi] && len[xi]-1 <= strlen(va[xi])){
 1211             const char *dBASE = va[xi];
 1212 #if defined(QSC)
 1213             const char *dNEXT = va[xi] + len[xi];
 1214 #else
 1215             int dSIZE = len[xi];
 1216 #endif
 1217         VStr_overflow("Xsscanf",F,L,AdTAIL,va[xi],strlen(va[xi]),len[xi],"\"%s\" -> \"%s\" $%d",fmt,yfmt,xi);
 1218             noverflow++;
 1219 
 1220             /* 9.2.5 sa[] and sc[] is introduced in 8.11.0-pre2 to
 1221              * try fix mad str[N] = '\0'; for "%Ns" format spec.
 1222              * [DeleGate:12693]
 1223              * Now it is not necessary and halmful.
 1224              * sc[] which is likely non '\0' should not be
 1225              * restored at least in this case, since it is halmful
 1226              * making unterminated string.
 1227              */
 1228             continue;
 1229         }
 1230         if( 0 < len[xi] ){
 1231             *sa[xi] = sc[xi];
 1232         }
 1233     }
 1234     if( noverflow )
 1235         if( debug_flags & DBG_ABORT ) abort();
 1236     return xn;
 1237 }
 1238 
 1239 #if defined(UNDER_CE)
 1240 char *XX_fgets(PVStr(buf),int siz,FILE *fp);
 1241 #else
 1242 #define XX_fgets(buf,siz,fp) 0
 1243 #endif
 1244 
 1245 char *Xfgets(PVStr(d),int siz,FILE *fp){
 1246     char *dp; /**/
 1247     int ch;
 1248     int i;
 1249     const char *dtail = dTAIL;
 1250 
 1251     if( outofrange("Xfgets",BVStr(d),0) ){
 1252         return Notify((char*)NULL);
 1253     }
 1254     if( siz <= 1 ){
 1255         VStr_overflow("Xfgets",dFILE,dLINE,AdTAIL,d,0,siz,"(size<=1)");
 1256         return NULL;
 1257     }
 1258 
 1259     dp = (char*)d;
 1260     if( isWindowsCE() ){
 1261         dp = XX_fgets(BVStr(d),siz,fp);
 1262         i = dp - d;
 1263     }else
 1264     for( i = 0; i < siz; i++ ){
 1265         /*
 1266         if( dTAIL <= dp ){
 1267         */
 1268         if( dtail <= dp ){
 1269             break;
 1270         }
 1271         ch = getc(fp);
 1272         if( ch == EOF ){
 1273             if( fpop_fd(fp) ){
 1274                 ch = getc(fp);
 1275             }
 1276         }
 1277         if( ch == EOF ){
 1278             break;
 1279         }
 1280         *dp++ = ch;
 1281         if( ch == '\n' ){
 1282             break;
 1283         }
 1284     }
 1285     *dp = 0;
 1286     if( dTAIL <= dp && dTAIL+1 < d+siz ){
 1287         VStr_overflow("Xfgets",dFILE,dLINE,AdTAIL,d,i,siz,"");
 1288     }
 1289     if( dp == d ){
 1290         return NULL;
 1291     }
 1292     return (char*)d;
 1293 }
 1294 
 1295 int ready_cc(FILE *fp);
 1296 unsigned int Xfread(FL_PAR,PVStr(d),int ez,int en,FILE *fp){
 1297     int z;
 1298     int rcc;
 1299 
 1300     setup_debug();
 1301     if( outofrange("Xfread",BVStr(d),0) ){
 1302         return Notify(0);
 1303     }
 1304     if( dTAIL == 0 )
 1305         z = 0;
 1306     else    z = (char*)dTAIL - d + 1;
 1307 
 1308 /*
 1309  if( debug_flags & DBG_VERBOSE )
 1310  fprintf(stderr,"## [%d] Xfread (%s:%d) %d/%d\n",
 1311     getpid(),dFILE,dLINE, ez*en,z);
 1312 */
 1313 
 1314     if( z < ez*en ){
 1315         VStr_overflow("Xfread",dFILE,dLINE,AdTAIL,d,ez*en,z,"");
 1316         return 0;
 1317     }
 1318     if( isWindowsCE() ){
 1319         rcc = XX_fread(FL_BAR,(char*)d,ez,en,fp);
 1320     }else
 1321     if( ready_cc(fp) == 0 ){
 1322         /* 9.9.4 MTSS to guard malloc() on the first fread */
 1323         /* but fread from a stream should be interruptable ... */
 1324         SSigMask sMask;
 1325         setSSigMask(sMask);
 1326         rcc = fread((char*)d,ez,en,fp);
 1327         resetSSigMask(sMask);
 1328     }else
 1329     rcc = fread((char*)d,ez,en,fp);
 1330     return rcc;
 1331 }
 1332 
 1333 #endif
 1334 
 1335 #if !defined(WITH_QVSTR)
 1336 int Ysprintf(PVStr(dst),PCStr(fmt),...){
 1337     IStr(afmt,256);
 1338     int n;
 1339     VARGS(16,fmt);
 1340 
 1341     if( modifyFmt(fmt,AVStr(afmt),sizeof(afmt)) ){
 1342         fmt = afmt;
 1343     }
 1344     n = sprintf((char*)dst,fmt,VA16);
 1345     return n;
 1346 }
 1347 #endif
 1348 int Ysscanf(PCStr(str),PCStr(fmt),...){
 1349     int ne;
 1350     IStr(afmt,256);
 1351     VARGS(16,fmt);
 1352 
 1353     if( NO_ll_Fmt() ){
 1354         if( modifyFmt(fmt,AVStr(afmt),sizeof(afmt)) ){
 1355             fmt = afmt;
 1356         }
 1357     }
 1358     ne = sscanf(str,fmt,VA16);
 1359     return ne;
 1360 }
 1361 static int floatFmt(PCStr(fmt)){
 1362     char fc;
 1363     const char *fp;
 1364 
 1365     for( fp = fmt; fc = *fp; fp++ ){
 1366         if( fc == '%' ){
 1367             if( fp[1] == '-' )
 1368                 fp++;
 1369             while( fc = *++fp ){
 1370                 if( fc != '*' && fc != '.' )
 1371                 if( fc < '0' || '9' < fc )
 1372                     break;
 1373             }
 1374             if( fc == 'f' )
 1375                 return 1;
 1376             if( fc == 0 )
 1377                 break;
 1378         }
 1379     }
 1380     return 0;
 1381 }
 1382 
 1383 #if !defined(WITH_QVSTR)
 1384 /*
 1385  * Xsscanf() / Xsprintf() should be redefined to be with modifyFmt()
 1386  * to care "%lld" on Windows
 1387  */
 1388 #endif
 1389 
 1390 #ifdef NOVSNPRINTF
 1391 int NoVFPRINTF = 1;
 1392 #else
 1393 int NoVFPRINTF = 0;
 1394 #endif
 1395 
 1396 #undef fprintf
 1397 int curLogFd();
 1398 FILE *curLogFp();
 1399 FILE *logMonFp();
 1400 FILE *logTeeFp;
 1401 
 1402 int FMT_Xfprintf(FILE *fp,const char *fmt,...){
 1403     int rcode;
 1404     CStr(llfmt,1024);
 1405 
 1406     if( modifyFmt(fmt,AVStr(llfmt),sizeof(llfmt)) ){
 1407         fmt = llfmt;
 1408     }
 1409     /*
 1410     rcode = fprintf(fp,fmt,VA16);
 1411     */
 1412     if( !NoVFPRINTF ){
 1413         va_list nap;
 1414         va_start(nap,fmt);
 1415         if( isWindowsCE() ){
 1416             rcode = XX_vfprintf(fp,fmt,nap);
 1417         }else
 1418         rcode = vfprintf(fp,fmt,nap);
 1419         va_end(nap);
 1420         /*
 1421         if( fp == curLogFp() ){
 1422         */
 1423         if( fp == curLogFp() || fileno(fp) == curLogFd() ){
 1424             if( lCONSOLE() && logTeeFp ){
 1425                 va_start(nap,fmt);
 1426                 vfprintf(logTeeFp,fmt,nap);
 1427                 va_end(nap);
 1428                 fflush(logTeeFp);
 1429             }else
 1430             if( lCONSOLE() && fp != stderr ){
 1431                 va_start(nap,fmt);
 1432                 vfprintf(stderr,fmt,nap);
 1433                 va_end(nap);
 1434                 fflush(stderr);
 1435             }
 1436             if( logMonFp() ){
 1437                 va_start(nap,fmt);
 1438                 vfprintf(logMonFp(),fmt,nap);
 1439                 va_end(nap);
 1440                 fflush(logMonFp());
 1441             }
 1442         }
 1443         if( fp == stdout || fp == stderr ){
 1444             if( logMonFp() && logMonFp() != fp ){
 1445                 va_start(nap,fmt);
 1446                 vfprintf(logMonFp(),fmt,nap);
 1447                 va_end(nap);
 1448                 fflush(logMonFp());
 1449             }
 1450         }
 1451     }else{
 1452         VARGS(16,fmt);
 1453         rcode = fprintf(fp,fmt,VA16);
 1454     }
 1455     if( isWindows() ){
 1456         if( fp == stderr ){
 1457             fflush(stderr);
 1458         }
 1459     }
 1460     return rcode;
 1461 }
 1462 
 1463 #undef fflush
 1464 
 1465 #define TR_FFLUSH 0
 1466 static fd_set *trace_files[8];
 1467 int traceFiles(int what,FILE *fp,int set){
 1468     int oval;
 1469     int fd;
 1470 
 1471     if( fp == NULL )
 1472         return -1;
 1473 
 1474     if( trace_files[what] == 0 ){
 1475         if( set < 0 ) return 0;
 1476         trace_files[what] = (fd_set*)malloc(sizeof(fd_set));
 1477         FD_ZERO(trace_files[what]);
 1478     }
 1479     fd = fileno(fp);
 1480     oval = FD_ISSET(fd,trace_files[what]);
 1481     switch( set ){
 1482         case 0: FD_CLR(fd,trace_files[what]); break;
 1483         case 1: FD_SET(fd,trace_files[what]); break;
 1484     }
 1485     return oval;
 1486 }
 1487 int fflushTrace(FILE *fp,int set){ return traceFiles(TR_FFLUSH,fp,set); }
 1488 
 1489 int inXfflush;
 1490 const char *FL_F_Xfflush;
 1491 int FL_L_Xfflush;
 1492 int Xfflush(FL_PAR, FILE *fp){
 1493     int rcode;
 1494 
 1495     if( fp == 0 ){
 1496         return -1;
 1497     }
 1498     if( !isWindowsCE() )
 1499     if( fileno(fp) < 0 ){
 1500         putfLog("##Xfflush(%d) suppressed <= %s:%d",fileno(fp),FL_BAR);
 1501         fpurge(fp);
 1502         return -1;
 1503     }
 1504     inXfflush = 1;
 1505     FL_F_Xfflush = FL_F;
 1506     FL_L_Xfflush = FL_L;
 1507     if( trace_files[TR_FFLUSH] && FD_ISSET(fileno(fp),trace_files[TR_FFLUSH]) ){
 1508         daemonlog("E","-- Xflush(%d/%X) %d\n",fileno(fp),p2i(fp),pendingcc(fp));
 1509     }
 1510     if( isWindowsCE() ){
 1511         rcode = XX_fflush_FL(FL_BAR,fp);
 1512     }else
 1513     rcode = fflush(fp);
 1514     inXfflush = 0;
 1515     return rcode;
 1516 }
 1517 
 1518 static int poppersist(const void *mp,FL_PAR,int ssi){
 1519     Alloc *ap;
 1520     int si;
 1521 
 1522     for( si = 1; si < elnumof(persistents); si++ ){
 1523         ap = &persistents[si];
 1524         if( ap->a_p == mp ){
 1525 HEAPVRB(stderr,"-dm clr persistent[%3d] S[%3d] %s:%d << [%d] %X %s:%d\n",
 1526 si,allocsp, ap->a_F,ap->a_L,ssi,p2i(ap->a_p), FL_BAR);
 1527             ap->a_p = 0;
 1528             return 1;
 1529         }
 1530     }
 1531     return 0;
 1532 }
 1533 static int pushpersist(Alloc *aap){
 1534     Alloc *ap;
 1535     int si;
 1536 
 1537     for( si = 1; si < elnumof(persistents); si++ ){
 1538         ap = &persistents[si];
 1539         if( ap->a_p == 0 ){
 1540             if( aap->a_F == ap->a_F && aap->a_L == ap->a_L ){
 1541             }else{
 1542             }
 1543 HEAPVRB(stderr,"-dm add persistent[%3d][%d] %s:%d (%d)\n",
 1544 allocsp,si,aap->a_F,aap->a_L,aap->a_z);
 1545             persistents[si] = *aap;
 1546             return si;
 1547         }
 1548     }
 1549     return 0;
 1550 }
 1551 /*
 1552 void *markPersistentMem(const void *mp){
 1553     Alloc *ap = 0;
 1554     int si;
 1555     int pi = 0;
 1556     Lock locked;
 1557 
 1558     if( !HEAPCHK ){
 1559         return (void*)mp;
 1560     }
 1561     doLock("",0);
 1562     for( si = allocsp-1; 0 <= si; si-- ){
 1563         ap = &allocs[si];
 1564         if( ap->a_p == mp ){
 1565             pi = pushpersist(ap);
 1566             ap->a_free = 2;
 1567             break;
 1568         }
 1569     }
 1570     unLock("",0);
 1571     return (void*)mp;
 1572 }
 1573 */
 1574 void markStackBase(void *mp){
 1575     Alloc *ap;
 1576     int si;
 1577     Lock locked;
 1578 
 1579     if( !HEAPCHK ){
 1580         return;
 1581     }
 1582     doLock("markStB",0);
 1583     for( si = allocsp-1; 0 <= si; si-- ){
 1584         ap = &allocs[si];
 1585         if( ap->a_p == mp ){
 1586             ap->a_base = 1;
 1587             break;
 1588         }
 1589     }
 1590     unLock("markStB-done",0);
 1591 }
 1592 void pushalloc(const char *wh,FL_PAR_P,unsigned int sz,void *mp){
 1593     Alloc *ap;
 1594     Lock locked;
 1595 
 1596     if( !HEAPCHK ){
 1597         return;
 1598     }
 1599     doLockB("pushalloc",0);
 1600     if( allocsp < elnumof(allocs) ){
 1601         if( 0 < lastpopend )
 1602         if( allocsp == lastpopend+1 ){
 1603             ap = &allocs[lastpopend];
 1604             if( ap->a_free == 0 )
 1605             if( ap->a_base == 0 )
 1606             {
 1607 HEAPERR(stderr,"-dm new persistent[%3d] %s:%d (%d) %s:%d\n",
 1608 allocsp,ap->a_F,ap->a_L,ap->a_z,FL_BAR);
 1609 fflush(stderr);
 1610             }
 1611         }
 1612         ap = &allocs[allocsp];
 1613         ap->a_F = FL_F;
 1614         ap->a_L = FL_L;
 1615         ap->a_p = mp;
 1616         ap->a_z = sz;
 1617         ap->a_free = 0;
 1618         ap->a_base = 0;
 1619         if( pstm ){
 1620             int pi;
 1621             pi = pushpersist(ap);
 1622         HEAPDBG(stderr,"-dm [%3d]%d %5X %8X %s:%d put [%d] by %s\n",
 1623             allocsp,pstm,sz,p2i(mp),FL_BAR,pi,wh);
 1624         }else{
 1625         HEAPDBG(stderr,"-dm [%3d]%d %5X %8X %s:%d pushed by %s\n",
 1626             allocsp,pstm,sz,p2i(mp),FL_BAR,wh);
 1627             allocsp++;
 1628         }
 1629     }
 1630 EXIT:
 1631     unLockB("pushalloc-done",0);
 1632 }
 1633 static void pops(const char *wh,FL_PAR){
 1634     Alloc *ap;
 1635     int si;
 1636 
 1637     lastpopend = 0;
 1638     for( si = allocsp-1; 0 <= si; si-- ){
 1639         ap = &allocs[si];
 1640         if( !ap->a_free ){
 1641             lastpopend = si;
 1642             break;
 1643         }
 1644         allocsp--;
 1645         HEAPDBG(stderr,"-dm [%3d]%d %5X %8X %s:%d %s %s:%d (POP)\n",
 1646             allocsp,ap->a_free,ap->a_z,p2i(ap->a_p),ap->a_F,ap->a_L,
 1647             wh,FL_BAR);
 1648     }
 1649 }
 1650 void popfree(const char *wh,FL_PAR,void *mp){
 1651     Alloc *ap;
 1652     int si;
 1653     Lock locked;
 1654     const void *op;
 1655     int poped = 0;
 1656 
 1657     if( !HEAPCHK ){
 1658         return;
 1659     }
 1660     doLockB("popfree",0);
 1661     for( si = allocsp-1; 0 <= si; si-- ){
 1662         ap = &allocs[si];
 1663         op = ap->a_p; /* might be cleared in poppersist() */
 1664         if( ap->a_free == 2 ){
 1665             if( poppersist(mp,FL_BAR,si) ){
 1666                 poped++;
 1667             }
 1668         }
 1669         if( op == mp ){
 1670             ap->a_free = 1;
 1671             HEAPDBG(stderr,"-dm [%3d]%d %5X %8X %s:%d %s %s:%d\n",
 1672                 si,ap->a_free,ap->a_z,p2i(mp),ap->a_F,ap->a_L,
 1673                 wh,FL_BAR);
 1674             pops(wh,FL_BAR);
 1675             goto EXIT;
 1676         }
 1677     }
 1678     if( poped || poppersist(mp,FL_BAR,si) ){
 1679         goto EXIT;
 1680     }
 1681     HEAPERR(stderr,"-dm [???](%d) %X %s %s:%d\n",allocsp,p2i(mp),wh,FL_BAR);
 1682 EXIT:
 1683     unLockB("popfree-done",0);
 1684 }
 1685 
 1686 int getthreadid();
 1687 static CriticalSec LockCSC;
 1688 #define EnterCSC(wh) \
 1689     if( numthreads() ){ \
 1690         setthread_FL(0,FL_BAR,wh); \
 1691         enterCSCX_FL(FL_ARG,LockCSC,300*1000); \
 1692         /* \
 1693         enterCSC(LockCSC); \
 1694         */ \
 1695     }
 1696 #define LeaveCSC(wh) \
 1697     if( numthreads() ){ \
 1698         setthread_FL(0,FL_BAR,wh); \
 1699         leaveCSC(LockCSC); \
 1700     }
 1701 
 1702 static void printLockStat(FL_PAR,PCStr(wh),int tid,int ntry,PCStr(act)){
 1703  IStr(msg,256);
 1704  Xsprintf(AVStr(msg),"-- %04X %.1f[%5d %d %X %s/%s:%d]%d*%s %s/%s:%d",
 1705         PRTID(tid),Time()-curLock.l_Time,
 1706         curLock.l_lid,curLock.l_lev,PRTID(curLock.l_tid),
 1707         curLock.l_wh,curLock.l_F,curLock.l_L,ntry,
 1708         act,wh,FL_BAR
 1709     );
 1710     strsubst(AVStr(msg),".cpp:",":");
 1711     fprintf(stderr,"%s\n",msg);
 1712     fflush(stderr);
 1713 }
 1714 static void printUnLockStat(FL_PAR,PCStr(wh),int tid,Lock locked,PCStr(act)){
 1715  IStr(msg,256);
 1716  Xsprintf(AVStr(msg),"-- %04X [%5d %d %X %s:%d] [%5d %d %X] %s %s %s:%d",
 1717         PRTID(tid),
 1718         curLock.l_lid,curLock.l_lev,PRTID(curLock.l_tid),
 1719         curLock.l_F,curLock.l_L,
 1720         locked.l_lid,locked.l_lev,PRTID(locked.l_tid),
 1721         act,wh,FL_BAR);
 1722     strsubst(AVStr(msg),".cpp:",":");
 1723     fprintf(stderr,"%s\n",msg);
 1724     fflush(stderr);
 1725 }
 1726 void msleep(int ms);
 1727 int waitLock(){
 1728     int wi;
 1729 
 1730     msleep(1);
 1731     for( wi = 0; wi < 10; wi++ ){
 1732         if( curLock.l_lev <= 0 ){
 1733             break;
 1734         }
 1735         syslog_ERROR("-- waitLock %2d) %d %X <= %s:%d\n",
 1736             wi,curLock.l_lev,PRTID(curLock.l_tid),
 1737             curLock.l_F?curLock.l_F:"",curLock.l_L
 1738         );
 1739         msleep(100);
 1740     }
 1741     return wi;
 1742 }
 1743 static Lock doLock_FL(FL_PAR,PCStr(wh),int log){
 1744     int tid = getthreadid();
 1745     Lock preLock;
 1746     int li;
 1747     int ri;
 1748     int dbg = 0;
 1749     int clev;
 1750     int ctid;
 1751     int failed = 0;
 1752 
 1753     setupCSC("doLock",LockCSC,sizeof(LockCSC));
 1754     for( ri = 0; ri < 10; ri++ ) RETRY:{
 1755         EnterCSC(wh);
 1756         clev = curLock.l_lev;
 1757         if( curLock.l_lev == 0 || curLock.l_tid == tid ){
 1758             curLock.l_lev++;
 1759             curLock.l_lid++;
 1760             curLock.l_tid = tid;
 1761             curLock.l_wh = wh;
 1762             curLock.l_F = FL_F;
 1763             curLock.l_L = FL_L;
 1764             if( clev == 0 ){
 1765                 curLock.l_Time = Time();
 1766             }
 1767             preLock = curLock;
 1768             preLock.l_lev--;
 1769             LeaveCSC(wh);
 1770 
 1771             if( 2 < log && 1 < curLock.l_lev ){
 1772                 /* curLock.l_dbg = tid; */
 1773  printLockStat(FL_BAR,wh,tid,failed,"LOCKED+");
 1774             }else
 1775             if( 2 < log || 50 < failed ){
 1776  printLockStat(FL_BAR,wh,tid,failed,"LOCKED-");
 1777             }
 1778             return preLock;
 1779         }
 1780         LeaveCSC(wh);
 1781         for( li = 0; li < 100; li++ ){
 1782             EnterCSC(wh);
 1783             clev = curLock.l_lev;
 1784             LeaveCSC(wh);
 1785             if( clev == 0 ){
 1786                 if( 80 < li ){
 1787  printLockStat(FL_BAR,wh,tid,failed,"RETRY-a");
 1788                     /* curLock.l_dbg = tid; */
 1789                 }
 1790                 goto RETRY;
 1791             }
 1792             usleep(10*1000);
 1793             failed++;
 1794         }
 1795  printLockStat(FL_BAR,wh,tid,failed,"RETRY-b");
 1796     }
 1797  printLockStat(FL_BAR,wh,tid,failed,"RESET ---- !!!!");
 1798 
 1799     if( numthreads() ){
 1800         /* should do destroy the CriticalSec here ... */
 1801         /*
 1802         this causes SEGV
 1803         bzero(LockCSC,sizeof(LockCSC));
 1804         */
 1805         /*
 1806         curLock = noLock;
 1807         */
 1808         curLock.l_lev = 0;
 1809     }
 1810     return noLock;
 1811 }
 1812 static void unLock_FL(FL_PAR,PCStr(wh), int log,Lock locked){
 1813     int tid = getthreadid();
 1814 
 1815     EnterCSC(wh);
 1816     if( curLock.l_tid == tid ){
 1817         if( 3 < log || curLock.l_dbg )
 1818  printUnLockStat(FL_BAR,wh,TID,locked,"unLocked");
 1819 
 1820         curLock.l_lev = locked.l_lev;
 1821         curLock.l_tid = locked.l_tid;
 1822         if( curLock.l_dbg == tid && curLock.l_lev == 0 ){
 1823             curLock.l_dbg = 0;
 1824         }
 1825     }else{
 1826  printUnLockStat(FL_BAR,wh,TID,locked,"unLock ABNORMAL");
 1827     }
 1828     LeaveCSC(wh);
 1829 }
 1830 int heapLock(FL_PAR,void *locked){
 1831     *(Lock*)locked = doLock_FL(FL_BAR,"heapLock",0);
 1832     return 0;
 1833 }
 1834 int heapUnLock(FL_PAR,void *locked){
 1835     unLock_FL(FL_BAR,"heapUnLock",2,*(Lock*)locked);
 1836     return 0;
 1837 }
 1838 
 1839 typedef struct {
 1840     const char *fx_wh;
 1841     const char *fx_F;
 1842     int    fx_L;
 1843     FILE * fx_fp;
 1844     int    fx_fd;
 1845 } FILEY;
 1846 #define NUM_FILEY 256
 1847 static FILEY filexs[NUM_FILEY];
 1848 int actFILEY;
 1849 int numFILEY;
 1850 void dumpFILEY(FILE *out){
 1851     int fn = 0;
 1852     int fi;
 1853     FILEY *fxp;
 1854     for( fi = 0; fi < NUM_FILEY; fi++ ){
 1855         fxp = &filexs[fi];
 1856         if( fxp->fx_wh )
 1857         if( fxp->fx_fp )
 1858         {
 1859             porting_dbg("--FY(%2d)(%2d)[%2d]%X %6s << %s:%d",
 1860                 fn++,fi,fxp->fx_fd,p2i(fxp->fx_fp),
 1861                 fxp->fx_wh,fxp->fx_F,fxp->fx_L);
 1862         }
 1863     }
 1864     porting_dbg("--FY act=%d / total=%d",actFILEY,numFILEY);
 1865 }
 1866 static void add_FILEY1(FL_Par,const char *wh,FILE *fp){
 1867     int fi;
 1868     FILEY *fxp;
 1869     int added = 0;
 1870 
 1871     for( fi = 0; fi < NUM_FILEY; fi++ ){
 1872         fxp = &filexs[fi];
 1873         if( fxp->fx_fp == fp ){
 1874 porting_dbg("--FY[%d]%X adding dup (%s)%s:%d[%d] >>> (%s)%s:%d[%d]",
 1875 fi,p2i(fp),fxp->fx_wh,fxp->fx_F,fxp->fx_L,fxp->fx_fd,
 1876 wh,FL_F,FL_L,fileno(fp));
 1877             fxp->fx_fp = 0;
 1878             actFILEY--;
 1879         }
 1880         if( fxp->fx_fp == 0 ){
 1881             fxp->fx_wh = wh;
 1882             fxp->fx_F = FL_F;
 1883             fxp->fx_L = FL_L;
 1884             fxp->fx_fp = fp;
 1885             fxp->fx_fd = fileno(fp);
 1886             added = 1;
 1887             actFILEY++;
 1888             if( numFILEY < actFILEY )
 1889                 numFILEY = actFILEY;
 1890             break;
 1891         }
 1892     }
 1893     if( added == 0 ){
 1894         porting_dbg("--FY[%d] cannot add %X %s << %s:%d",fi,p2i(fp),
 1895             wh,FL_F,FL_L);
 1896     }
 1897 }
 1898 void del_FILEY1(FL_Par,const char *wh,FILE *fp){
 1899     int fi;
 1900     FILEY *fxp;
 1901     int deled = 0;
 1902 
 1903     for( fi = 0; fi < NUM_FILEY; fi++ ){
 1904         fxp = &filexs[fi];
 1905         if( fxp->fx_fp == fp ){
 1906             fxp->fx_wh = wh;
 1907             fxp->fx_F = FL_F;
 1908             fxp->fx_L = FL_L;
 1909             fxp->fx_fp = 0;
 1910             deled = 1;
 1911             actFILEY--;
 1912             break;
 1913         }
 1914     }
 1915     if( deled == 0 ){
 1916         porting_dbg("--FY[%d] not found %X %s << %s:%d",fi,p2i(fp),
 1917             wh,FL_F,FL_L);
 1918     }
 1919 }
 1920 void add_FILEY(FL_Par,const char *wh,FILE *fp){
 1921     Lock locked;
 1922 
 1923     if( !lMEMUSAGE() ){ return; }
 1924     if( fp == 0 )
 1925         return;
 1926     if( !lSINGLEP() )
 1927         return;
 1928     doLockB(wh,2);
 1929     add_FILEY1(FL_Bar,wh,fp);
 1930     unLockB(wh,2);
 1931 }
 1932 void del_FILEY(FL_Par,const char *wh,FILE *fp){
 1933     Lock locked;
 1934 
 1935     if( !lMEMUSAGE() ){ return; }
 1936     if( fp == 0 )
 1937         return;
 1938     if( !lSINGLEP() )
 1939         return;
 1940     doLockB(wh,2);
 1941     del_FILEY1(FL_Bar,wh,fp);
 1942     unLockB(wh,2);
 1943 }
 1944 
 1945 
 1946 #undef malloc
 1947 const char *FL_F_Malloc;
 1948 int FL_L_Malloc;
 1949 int inMalloc;
 1950 void *Xmalloc(FL_PAR,int pstm,unsigned int z){
 1951     Lock locked;
 1952     void *mp;
 1953     sigfunc sig = setsig("Xmalloc",FL_BAR,z);
 1954     SSigMask sMask; setSSigMask(sMask);
 1955     doLockB("malloc",0);
 1956     inMalloc++; FL_F_Malloc = "Xmalloc"; FL_L_Malloc = __LINE__;
 1957     mp = malloc(z);
 1958     inMalloc--;
 1959     unLockB("malloc-done",0);
 1960     resetSSigMask(sMask);
 1961     signal(SIGSEGV,sig);
 1962     if( mp == NULL ){
 1963         errno = ENOMEM;
 1964         Abort(0,"FAILED Xmalloc(%d) %s:%d\n",z,FL_BAR);
 1965     }
 1966     pushalloc("malloc",FL_BAR,pstm,z,mp);
 1967     return mp;
 1968 }
 1969 #undef calloc
 1970 void *Xcalloc(FL_PAR,int pstm,unsigned int n,unsigned int z){
 1971     Lock locked;
 1972     void *mp;
 1973     sigfunc sig = setsig("Xcalloc",FL_BAR,z);
 1974     SSigMask sMask; setSSigMask(sMask);
 1975     doLockB("calloc",0);
 1976     inMalloc++; FL_F_Malloc = "Xcalloc"; FL_L_Malloc = __LINE__;
 1977     mp = calloc(n,z);
 1978     inMalloc--;
 1979     unLockB("calloc-done",0);
 1980     resetSSigMask(sMask);
 1981     signal(SIGSEGV,sig);
 1982     if( mp == NULL ){
 1983         Abort(0,"FAILED Xcalloc(%d,%d) %s:%d\n",n,z,FL_BAR);
 1984     }
 1985     pushalloc("calloc",FL_BAR,pstm,n*z,mp);
 1986     return mp;
 1987 }
 1988 
 1989 #undef free
 1990 int numthreads();
 1991 int mallocSize(void *p);
 1992 void Xfree(FL_PAR,void *p){
 1993     Lock locked;
 1994     sigfunc sig = setsig("Xfree",FL_BAR,-1);
 1995     SSigMask sMask; setSSigMask(sMask);
 1996     doLockB("free",1);
 1997     inMalloc++; FL_F_Malloc = "Xfree"; FL_L_Malloc = __LINE__;
 1998     free(p);
 1999     inMalloc--;
 2000     unLockB("free-done",1);
 2001     resetSSigMask(sMask);
 2002     signal(SIGSEGV,sig);
 2003     popfree("free",FL_BAR,p);
 2004 }
 2005 #undef realloc
 2006 void *Xrealloc(FL_PAR,int pstm,void *p,unsigned int z){
 2007     Lock locked;
 2008     void *mp;
 2009     int oz;
 2010     sigfunc sig = setsig("Xrealloc",FL_BAR,z);
 2011     SSigMask sMask; setSSigMask(sMask);
 2012     oz = p ? mallocSize(p) : 0;
 2013     doLockB("realloc",1);
 2014     inMalloc++; FL_F_Malloc = "Xrealloc"; FL_L_Malloc = __LINE__;
 2015     mp = realloc(p,z);
 2016     inMalloc--;
 2017     unLockB("realloc-done",1);
 2018     resetSSigMask(sMask);
 2019 
 2020 if( HEAPCHK )
 2021 if( p != 0 && mp != p )
 2022 porting_dbg("realloc(%X/%d,%d)=%X %s:%d",
 2023 p2i(p),oz,z,p2i(mp),FL_BAR);
 2024 
 2025     if( mp == NULL ){
 2026         int serrno = errno;
 2027         int nerrno;
 2028 
 2029         //msleep(10);
 2030         errno = 0;
 2031         setSSigMask(sMask);
 2032         doLockB("realloc-2",1);
 2033         mp = realloc(p,z);
 2034         unLockB("realloc-2-done",1);
 2035         resetSSigMask(sMask);
 2036         nerrno = errno;
 2037 
 2038 porting_dbg("Xrealloc(%X/%d,%d)=%X %s:%d errno=%d,%d th=%d/%d",
 2039 p2i(p),oz,z,p2i(mp),FL_BAR,serrno,nerrno,actthreads(),numthreads());
 2040 
 2041     }
 2042 
 2043     if( mp != NULL ){
 2044         if( mp != p ){
 2045             popfree("realloc",FL_BAR,p);
 2046             pushalloc("realloc",FL_BAR,pstm,z,mp);
 2047         }
 2048     }
 2049 
 2050     signal(SIGSEGV,sig);
 2051     if( mp == NULL ){
 2052         Abort(0,"FAILED Xrealloc(%X,%d) %s:%d\n",p,z,FL_BAR);
 2053     }
 2054     return mp;
 2055 }
 2056 
 2057 #undef putenv
 2058 #if isWindowsCE()
 2059 int putenv(const char*env);
 2060 #endif
 2061 int Xputenv_FL(FL_PAR,const char *env){
 2062     Lock locked;
 2063     int rcode;
 2064     if( lMULTIST() ){
 2065         doLockB("putenv",1);
 2066         rcode = putenv((char*)env);
 2067         if( LOG_VERBOSE )
 2068         porting_dbg("putenv(%s)",env);
 2069         unLockB("putenv-done",1);
 2070     }else{
 2071         SSigMask sMask;
 2072         setSSigMask(sMask);
 2073         rcode = putenv((char*)env);
 2074         resetSSigMask(sMask);
 2075     }
 2076     return rcode;
 2077 }
 2078 
 2079 #ifdef _MSC_VER
 2080 int open_FL(FL_PAR, const char *path,int flag);
 2081 int close_FL(FL_PAR, int fd);
 2082 int dup_FL(FL_PAR, int fd);
 2083 int dup2_FL(FL_PAR, int sfd,int dfd);
 2084 int socketpair_FL(FL_PAR, int d,int t,int p,int v[]);
 2085 int accept_FL(FL_PAR, int fdd,void *sa,int *len);
 2086 int socket_FL(FL_PAR,int d,int t,int p);
 2087 
 2088 int Xopen_FL(FL_PAR, const char *path,int flag){
 2089     int rcode;
 2090     if( isWindows() ){
 2091         Lock locked;
 2092         doLockB("open",2);
 2093         rcode = open_FL(FL_BAR,path,flag);
 2094         unLockB("open-done",2);
 2095     }else{
 2096         rcode = open(path,flag);
 2097     }
 2098     return rcode;
 2099 }
 2100 /* may block seconds for linger. */
 2101 int Xclose_FL(FL_PAR, int fd){
 2102     int rcode;
 2103     if( isWindows() ){
 2104         Lock locked;
 2105         doLockB("close",2);
 2106         rcode = close_FL(FL_BAR,fd);
 2107         unLockB("close-done",2);
 2108     }else{
 2109         rcode = close(fd);
 2110     }
 2111     return rcode;
 2112 }
 2113 int Xdup_FL(FL_PAR, int fd){
 2114     int rcode;
 2115     if( isWindows() ){
 2116         Lock locked;
 2117         doLockB("dup",2);
 2118         rcode = dup_FL(FL_BAR,fd);
 2119         unLockB("dup-done",2);
 2120     }else{
 2121         rcode = dup(fd);
 2122     }
 2123     return rcode;
 2124 }
 2125 int Xdup2_FL(FL_PAR, int sfd,int dfd){
 2126     int rcode;
 2127     if( isWindows() ){
 2128         Lock locked;
 2129         doLockB("dup2",2);
 2130         rcode = dup2_FL(FL_BAR,sfd,dfd);
 2131         unLockB("dup2-done",2);
 2132     }else{
 2133         rcode = dup2(sfd,dfd);
 2134     }
 2135     return rcode;
 2136 }
 2137 int Xsocketpair_FL(FL_PAR,int d,int t,int p,int v[]){
 2138     int rcode;
 2139     if( isWindows() ){
 2140         Lock locked;
 2141         doLockB("socketpair",2);
 2142         rcode = socketpair_FL(FL_BAR,d,t,p,v);
 2143         unLockB("socketpair-done",2);
 2144     }else{
 2145         rcode = socketpair(d,t,p,v);
 2146     }
 2147     return rcode;
 2148 }
 2149 int Xaccept_FL(FL_PAR,int fd,void *sa,int *len){
 2150     int rcode;
 2151     if( isWindows() ){
 2152         Lock locked;
 2153         doLockB("accept",2);
 2154         rcode = accept_FL(FL_BAR,fd,sa,len);
 2155         unLockB("accept-done",2);
 2156     }else{
 2157         rcode = accept(fd,sa,len);
 2158     }
 2159     return rcode;
 2160 }
 2161 int Xsocket_FL(FL_PAR,int d,int t,int p){
 2162     int rcode;
 2163     if( isWindows() ){
 2164         Lock locked;
 2165         doLockB("socket",2);
 2166         rcode = socket_FL(FL_BAR,d,t,p);
 2167         unLockB("socket-done",2);
 2168     }else{
 2169         rcode = socket(d,t,p);
 2170     }
 2171     return rcode;
 2172 }
 2173 
 2174 #undef filemmap
 2175 #undef freemmap
 2176 MMap *Xfilemmap_FL(FL_PAR,PCStr(fname),PCStr(fmode),int off,int len){
 2177     MMap *mm;
 2178     if( isWindows() ){
 2179         Lock locked;
 2180         doLockB("filemmap",2);
 2181         mm = filemmap(fname,fmode,off,len);
 2182         unLockB("filemmap-done",2);
 2183     }else{
 2184         mm = filemmap(fname,fmode,off,len);
 2185     }
 2186     return mm;
 2187 }
 2188 int Xfreemmap_FL(FL_PAR,MMap *mm){
 2189     int rcode;
 2190     if( isWindows() ){
 2191         Lock locked;
 2192         doLockB("freemmap",2);
 2193         rcode = freemmap(mm);
 2194         unLockB("freemmap-done",2);
 2195     }else{
 2196         rcode = freemmap(mm);
 2197     }
 2198     return rcode;
 2199 }
 2200 
 2201 #else
 2202 #endif
 2203 
 2204 static int ignRet;
 2205 int *IgnRet(FL_PAR){
 2206     if( lRETERR() ){
 2207         fprintf(stderr,"--{%d} %s:%d\n",ignRet,FL_BAR);
 2208     }
 2209     return &ignRet;
 2210 }