"Fossies" - the Fresh Open Source Software Archive

Member "delegate9.9.13/src/process.c" (30 Jan 2010, 12254 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 "process.c" see the Fossies "Dox" file reference documentation.

    1 /*////////////////////////////////////////////////////////////////////////
    2 Copyright (c) 1997-2000 Yutaka Sato and ETL,AIST,MITI
    3 Copyright (c) 2001-2006 National Institute of Advanced Industrial Science and Technology (AIST)
    4 AIST-Product-ID: 2000-ETL-198715-01, H14PRO-049, H15PRO-165, H18PRO-443
    5 
    6 Permission to use this material for noncommercial and/or evaluation
    7 purpose, copy this material for your own use, and distribute the copies
    8 via publicly accessible on-line media, without fee, is hereby granted
    9 provided that the above copyright notice and this permission notice
   10 appear in all copies.
   11 AIST MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY OF THIS
   12 MATERIAL FOR ANY PURPOSE.  IT IS PROVIDED "AS IS", WITHOUT ANY EXPRESS
   13 OR IMPLIED WARRANTIES.
   14 /////////////////////////////////////////////////////////////////////////
   15 Content-Type:   program/C; charset=US-ASCII
   16 Program:    process.c
   17 Author:     Yutaka Sato <ysato@etl.go.jp>
   18 Description:
   19 History:
   20     970117  created
   21 //////////////////////////////////////////////////////////////////////#*/
   22 #include <stdio.h>
   23 #include "delegate.h"
   24 #include "fpoll.h"
   25 #include "param.h"
   26 #include "file.h"
   27 #include "proc.h"
   28 #include "vsignal.h"
   29 
   30 int inherent_fork(PCStr(F),int L);
   31 #define INHERENT_fork() inherent_fork(__FILE__,__LINE__)
   32 
   33 extern const char **main_argv;
   34 
   35 int MountSerno(PCStr(opts));
   36 const char *setMountOptions(FL_PAR,Connection *Conn,PCStr(opts));
   37 typedef struct {
   38     int sa_mountserno;
   39     int sa_moptslen;
   40 } SpawnArgs;
   41 
   42 #define CLEAR(m) (Conn->m = 0)
   43 
   44 static void clearConnPTR(Connection *Conn)
   45 {
   46     CLEAR(sv_toServ);
   47     CLEAR(cl_user);
   48     /*
   49     CLEAR(cl_FromCbuff);
   50     */
   51     STX_cb.cb_buff = 0;
   52     CLEAR(gw.p_auth);
   53     CLEAR(gw_path);
   54     CLEAR(sv_dflt.p_auth);
   55     CLEAR(ht_LockedByClient);
   56     /*
   57     UTfree(&D_REQUESTtag);
   58     */
   59 if( D_REQUESTtag.ut_addr ) sv1log("#### clearConnPTR: clearing D_REQUEST\n");
   60     UTclear(&D_REQUESTtag);
   61 
   62     bzero(&Conn->dg_fthread,sizeof(Conn->dg_fthread));
   63     bzero(&Conn->dg_sthread,sizeof(Conn->dg_sthread));
   64     bzero(ConnCSC,sizeof(ConnCSC));
   65 }
   66 
   67 extern int CHILD_SERNO;
   68 extern int CHILD_SERNO_MULTI;
   69 int callFilter(Connection *Conn,int ac,const char *av[])
   70 {   int ein,eout,rcc;
   71     int tcc = 0;
   72     int fio[2];
   73     FILE *in,*out;
   74     const char *args;
   75     int sock;
   76     int rcode;
   77     SpawnArgs spawnArgs;
   78 
   79     iLog("--- callFilter(%X,%d,%X)",p2i(Conn),ac,p2i(av));
   80     /*
   81     sscanf(av[2],"%d/%d",&ein,&eout);
   82     in = fdopen(ein,"r");
   83     */
   84     /*
   85     sscanf(av[2],"%d/%d/%d/%d",&fio[0],&fio[1],&ein,&eout);
   86     */
   87     sscanf(av[2],"%d/%d/%d/%d %d/%d",&fio[0],&fio[1],&ein,&eout,
   88         &CHILD_SERNO,&CHILD_SERNO_MULTI);
   89     in = fdopen(fio[0],"r");
   90     close(fio[1]);
   91 
   92     rcc = fread(&spawnArgs,1,sizeof(spawnArgs),in);
   93     tcc += rcc;
   94     if( rcc != sizeof(spawnArgs) ){
   95         /* 9.9.4 MTSS the caller might exited with signal */
   96         fprintf(stderr,"[%d] --- callFilter sA rcc=%d/%d %d\n",
   97             getpid(),rcc,isizeof(spawnArgs),tcc);
   98         fflush(stderr);
   99         _exit(-1);
  100     }
  101     rcc = fread(Conn,1,sizeof(Connection),in);
  102     tcc += rcc;
  103     if( rcc != sizeof(Connection) ){
  104         fprintf(stderr,"[%d] --- callFilter Co rcc=%d/%d %d\n",
  105             getpid(),rcc,isizeof(Connection),tcc);
  106         fflush(stderr);
  107         _exit(-1);
  108     }
  109 
  110     iLog("--- callFilter %d %X %X %X+%d %X:%X %d:%d:%d %X %X",rcc,
  111         Conn->cx_magic,LOG_bugs,p2i(Conn->cl_reqbuf),Conn->cl_reqbufsize,
  112         p2i(&D_REQUESTtag),p2i(D_REQUESTtag.ut_addr),
  113         isizeof(int),isizeof(char*),isizeof(Connection),
  114         xp2i(clearConnPTR),xp2i(callFilter)
  115     );
  116     if( rcc != sizeof(Connection) ){
  117         void initABORT(int sig);
  118         bzero(Conn,sizeof(Conn)); /* dumped in initABORT() */
  119         initABORT(0);
  120         Finish(-1);
  121         return -1;
  122     }
  123     if( Conn->cl_reqbuf ){
  124         Conn->cl_reqbuf = (char*)malloc(Conn->cl_reqbufsize);
  125         iLog("--- qbuf=%X+%d",p2i(Conn->cl_reqbuf),Conn->cl_reqbufsize);
  126         rcc =
  127         fread(Conn->cl_reqbuf,1,Conn->cl_reqbufsize,in);
  128         tcc += rcc;
  129         if( rcc != Conn->cl_reqbufsize ){
  130             fprintf(stderr,"[%d] --- callFilter qb rcc=%d/%d %d\n",
  131                 getpid(),rcc,Conn->cl_reqbufsize,tcc);
  132             fflush(stderr);
  133             _exit(-1);
  134         }
  135         iLog("--- qbuf rcc=%d/%d",rcc,Conn->cl_reqbufsize);
  136     }
  137 
  138     clearConnPTR(Conn);
  139     fdopenLogFile(Conn->fi_logfd);
  140 
  141     if( 0 < Conn->fi_arglen ){
  142         args = (char*)malloc(Conn->fi_arglen);
  143         rcc = fread((char*)args,1,Conn->fi_arglen,in);
  144         tcc += rcc;
  145         if( rcc != Conn->fi_arglen ){
  146             fprintf(stderr,"[%d] --- callFilter fa rcc=%d/%d %d\n",
  147                 getpid(),rcc,Conn->fi_arglen,tcc);
  148             fflush(stderr);
  149             _exit(-1);
  150         }
  151     }else{
  152         args = NULL;
  153         rcc = 0;
  154     }
  155     iLog("--- callFilter args=%d/%d %X",rcc,Conn->fi_arglen,p2i(args));
  156 
  157     ClientSock = -1;
  158     if( Conn->fi_issock ){
  159         if( (sock = getclientsock()) < 0 )
  160         sock = Conn->fi_topeer;
  161         if( Conn->fi_dupclsock )
  162             ClientSock = sock;
  163     }else   sock = Conn->fi_topeer;
  164 
  165     if( spawnArgs.sa_mountserno ){
  166         IStr(opts,1024); /* opts[] can be empty */
  167         if( 0 < spawnArgs.sa_moptslen ){
  168             int len = sizeof(opts)-1;
  169             int occ;
  170             if( spawnArgs.sa_moptslen < len ){
  171                 len = spawnArgs.sa_moptslen;
  172             }
  173             occ = fread(opts,1,len,in);
  174             if( 0 <= occ ){
  175                 setVStrEnd(opts,occ);
  176             }
  177         }
  178         setMountOptions(FL_ARG,Conn,stralloc(opts));
  179     }
  180 
  181     fclose(in);
  182     if( Conn->fi_iomode & 1 ){
  183         close(eout);
  184         out = fdopen(sock,"w");
  185         in = fdopen(ein,"r");
  186     }else{
  187         in = fdopen(sock,"r");
  188         out = fdopen(eout,"w");
  189     }
  190 
  191     iLog("--- callFilter %X(%X,%X,%X,%d)",xp2i(Conn->fi_func),p2i(in),p2i(out),p2i(args),rcc);
  192     Verbose("## callFilter: %x[%d,%d]\n",xp2i(Conn->fi_func),fileno(in),fileno(out));
  193     rcode = (*Conn->fi_func)(Conn,in,out,args,rcc);
  194     Finish(rcode?1:0);
  195     return -1;
  196 }
  197 
  198 int spawnFilter(Connection *Conn,int iomode,int tofil[],int sock,iFUNCP func,PCStr(args))
  199 {   CStr(ein,32);
  200     int ac;
  201     const char *av[256]; /**/
  202     CStr(epath,1024);
  203     CStr(logtype,64);
  204     CStr(logtype2,64);
  205     int fin; /* input at the filter side */
  206     int fout; /* output at the DeleGate side */
  207     int pid;
  208     int wcc;
  209     int wi;
  210     int fio[2]; /* a pipe to inherit Conn. */
  211     FILE *out;
  212     SpawnArgs spawnArgs;
  213 
  214     iLog("--- spawnFilter sock=%d func=%X args=%X",sock,xp2i(func),p2i(args));
  215     fin = tofil[0];
  216     fout = tofil[1];
  217     pipeX(fio,8*1024);
  218     out = fdopen(fio[1],"w");
  219     sprintf(ein,"%d/%d/%d/%d %d/%d",fio[0],fio[1],fin,fout,
  220         CHILD_SERNO,CHILD_SERNO_MULTI);
  221     /*
  222     sprintf(ein,"%d/%d/%d/%d",fio[0],fio[1],fin,fout);
  223     */
  224     /*
  225     sprintf(ein,"%d/%d",fin,fout);
  226     */
  227 
  228     sprintf(epath,"%s=%s",P_EXEC_PATH,EXEC_PATH);
  229     ac = 0;
  230     av[ac++] = /*DeleGate1*/ "DeleGate";
  231     av[ac++] = /*FuncFILTER*/ "(Filter)";
  232     av[ac++] = ein;
  233     av[ac++] = epath;
  234 
  235     /*
  236     sprintf(logtype,"-L0x%x",LOG_type);
  237     */
  238     sprintf(logtype,"-L0x%x/%d",LOG_type,curLogFd());
  239     av[ac++] = logtype;
  240     if( LOG_type2 || LOG_bugs ){
  241         sprintf(logtype2,"-L20x%x/%x",LOG_type2,LOG_bugs);
  242         av[ac++] = logtype2;
  243     }
  244     ac += copy_param("f",elnumof(av)-ac,&av[ac],&main_argv[1]);
  245     av[ac] = NULL;
  246 
  247     Conn->fi_func = func;
  248     if( args == NULL )
  249         Conn->fi_arglen = 0;
  250     else    Conn->fi_arglen = strlen(args)+1;
  251     Conn->fi_iomode = iomode;
  252     Conn->fi_logfd  = curLogFd();
  253 
  254     if( file_isreg(sock) ){
  255         /* it might be TMPFILE() with CloseOnExec flag set */
  256         clearCloseOnExec(sock);
  257     }
  258     Conn->fi_topeer = sock;
  259     Conn->fi_dupclsock = 0;
  260     if( Conn->fi_issock = file_ISSOCK(sock) ){
  261         setclientsock(sock);
  262         if( sock == ClientSock
  263          || SocketOf(sock) == SocketOf(ClientSock) )
  264             Conn->fi_dupclsock = 1;
  265             
  266     }
  267 
  268     /* might be emulating spawn() on Unix */
  269     sigsetmask(sigblock(0) & ~sigmask(SIGHUP) );
  270 
  271     pid = Spawnvp("openFilter",EXEC_PATH,av);
  272     Verbose("## spawnFilter: %d -> %d\n",getpid(),pid);
  273     if( pid <= 0 ){
  274         /* 9.6.3 don't freeze in fwrite() to the pipe ... */
  275         fclose(out);
  276         close(fio[0]);
  277         daemonlog("F","spawnFilter: FAILED %d\n",pid);
  278         porting_dbg("--FATAL: spawnFilter: FAILED spawn %d",pid);
  279         putpplog("--FATAL: spawnFilter: FAILED spawn %d\n",pid);
  280         return pid;
  281     }
  282 
  283 /*
  284     wcc = write(fout,Conn,sizeof(Connection));
  285     if( Conn->cl_reqbuf )
  286         write(fout,Conn->cl_reqbuf,Conn->cl_reqbufsize);
  287     if( args != NULL )
  288         write(fout,args,strlen(args)+1);
  289 */
  290     close(fio[0]); /* close here to get EPIPE on write(fio[1]) */
  291 
  292     if( MountOptions ){
  293         spawnArgs.sa_mountserno = MountSerno(MountOptions);
  294         spawnArgs.sa_moptslen = strlen(MountOptions)+1;
  295     }else{
  296         spawnArgs.sa_mountserno = 0;
  297         spawnArgs.sa_moptslen = 0;
  298     }
  299     wcc = fwrite(&spawnArgs,1,sizeof(spawnArgs),out);
  300     wcc = fwrite(Conn,1,sizeof(Connection),out);
  301     if( Conn->cl_reqbuf )
  302         fwrite(Conn->cl_reqbuf,1,Conn->cl_reqbufsize,out);
  303     if( args != NULL )
  304         fwrite(args,1,strlen(args)+1,out);
  305     if( MountOptions && spawnArgs.sa_moptslen ){
  306         fwrite(MountOptions,1,spawnArgs.sa_moptslen,out);
  307         setMountOptions(FL_ARG,Conn,0);
  308     }
  309     fclose(out);
  310 
  311     /* If the iomode == READ then
  312      * must wait till the client finish to read the written environment
  313      * not to read it by myself.
  314      * (in the case of FFROMCL, payload data may be ready, but cannot
  315      *  identify whether or not it is env. data or payload data ...)
  316      * If the iomode == WRITE and filter is direct system-command then
  317      * must wait not to make buffered data be not passed to the filter.
  318      */
  319     /*
  320     if( iomode == 0 || iomode != 0 && 0 < PollIn(fin,1) ){
  321         sv1log("## wait the filter finish reading enviroment\n");
  322         msleep(100);
  323     }
  324     */
  325 
  326     return pid;
  327 }
  328 
  329 static int xproc(PCStr(what),int pid){
  330     fprintf(stderr,"----[%d] Fork(%s) detected exit of [%d]\n",
  331         getpid(),what,pid);
  332     return 0;
  333 }
  334 
  335 #if defined(__FreeBSD__)
  336 #define THREADSAFE_FORK 0
  337 #else
  338 #define THREADSAFE_FORK 1
  339 #endif
  340 int threadSafeFork(){
  341     if( actthreads() == 0 )
  342         return 1;
  343     if( THREADSAFE_FORK ){
  344         return 1;
  345     }
  346     return 0;
  347 }
  348 
  349 int ShutdownSocket(int fd);
  350 #define fth FTenv
  351 static int threadFilter(Connection *Conn,PCStr(fname),iFUNCP func,FILE *ioin,FILE *out,PCStr(args)){
  352     int code;
  353     IStr(buf,1);
  354     int osock;
  355 
  356     setthreadgid(0,STX_tid);
  357     osock = ClientSock;
  358     //ClientSock = dup(ClientSock);
  359     Verbose("-- F openFilter: %s [%d][%d] [%d]>>[%d]\n",
  360         fname, osock,ClientSock, FromS,ToC);
  361     // write(fileno(ioin),"\n",1); /* for sync. of thread_fork */
  362     PollIn(fileno(ioin),1000);
  363 
  364     clearConnPTR(Conn);
  365     code = (*func)(Conn,ioin,out,args);
  366     Verbose("-- F openFilter: DONE %d\n",code);
  367     fflush(out);
  368     ShutdownSocket(fileno(ioin));
  369     /*
  370     close(fth.f_sync[1]);
  371     */
  372     sv1log("-- F openFilter: EXIT(%d) %s\n",code,fname);
  373     return 0;
  374 }
  375 int waitFilterThreadX(Connection *Conn){
  376     int rdy,err;
  377     double St = Time();
  378     if( fth.f_tid ){
  379         /*
  380         rdy = PollIn(fth.f_sync[0],3*1000);
  381         */
  382         err = thread_wait(fth.f_tid,10*1000);
  383         sv1log("--a--waitFilterThreadX: %X err=%d (%.3f)\n",
  384             fth.f_tid,err,Time()-St);
  385         /*
  386         sv1log("--a--waitFilterThreadX: rdy[%d]=%d %X err=%d\n",
  387             fth.f_sync[0],rdy,fth.f_tid,err);
  388         //fclose(fth.f_out);
  389         close(fth.f_sync[0]);
  390         */
  391         fclose(fth.f_ioin);
  392         if( fth.f_Conn->cl.p_closed ){
  393             ClientEOF = 2 | fth.f_Conn->cl.p_closed;
  394         }
  395         if( fth.f_Conn->cl_tcCLOSED ){
  396             tcCLOSED = 2 | fth.f_Conn->cl_tcCLOSED;
  397         }
  398         sv1log("## [%d]%X threadF WAIT %X ClientEOF=%d/%d\n",
  399             STX_tix,TID,0xFFF&fth.f_tid,ClientEOF,tcCLOSED);
  400 
  401         free(fth.f_Conn);
  402         fth.f_Conn = 0;
  403         fth.f_tid = 0;
  404         fth.f_ptid = 0;
  405         return 0;
  406     }
  407     return -1;
  408 }
  409 static void relay(FILE *in,FILE *out){
  410     IStr(buf,1024);
  411     while( fgets(buf,sizeof(buf),in) ){
  412         fputs(buf,out);
  413     }
  414     fclose(in);
  415     //fcloseFILE(out);
  416 }
  417 FILE *openFilter(Connection *Conn,PCStr(fname),iFUNCP func,FILE *out,PCStr(args))
  418 {   int pid;
  419     int toc[2];
  420     FILE *ioin;
  421 
  422     if( lSINGLEP() ){
  423         FILE *ioout;
  424         Connection *dupConn;
  425         extern int BREAK_STICKY;
  426 
  427         BREAK_STICKY = 1;
  428         Socketpair(toc);
  429         /*
  430         Socketpair(fth.f_sync);
  431         */
  432         ioin = fdopen(toc[0],"r");
  433         ioout = fdopen(toc[1],"w");
  434         dupConn = (Connection*)malloc(sizeof(Connection));
  435         *dupConn = *Conn;
  436         fth.f_Conn = dupConn;
  437         fth.f_ioin = ioin;
  438         fth.f_ptid = STX_tid;
  439 /*
  440         fth.f_tid = thread_fork(0x80000,STX_tid,"threadFilter",(IFUNCP)threadFilter,
  441 */
  442         fth.f_tid = thread_fork(0x100000,STX_tid,"threadFilter",(IFUNCP)threadFilter,
  443             dupConn,fname,func,ioin,out,args);
  444         return ioout;
  445     }
  446     /*
  447     pipe(toc);
  448     */
  449     pipeX(toc,8*1024);
  450     /*
  451     if( INHERENT_fork() ){
  452     */
  453     /*
  454     if( INHERENT_fork() && threadSafeFork() ){
  455     */
  456     if( INHERENT_fork() && threadSafeFork() && !lEXECFILTER() ){
  457         /*
  458         if( Fork("openFilter") == 0 ){
  459         */
  460         /*
  461         if( (pid = Fork("openFilter")) == 0 ){
  462         */
  463         if( (pid = ForkX("openFilter",xproc)) == 0 ){
  464             close(toc[1]);
  465             ioin = fdopen(toc[0],"r");
  466             (*func)(Conn,ioin,out,args);
  467             Finish(0);
  468         }
  469     }else{
  470         fflush(out);
  471         pid = spawnFilter(Conn,1,toc,fileno(out),func,args);
  472     }
  473     Conn->fi_pid = pid;
  474     close(toc[0]);
  475     return fdopen(toc[1],"w");
  476 }