1 #include <fcntl.h>
   2 #include <stdio.h>
   3 #include <stdlib.h>
   4 #include <unistd.h>
   5 
   6 #include "unixprocess_md.h"
   7 
   8 extern int errno;
   9 
  10 #define ALLOC(X,Y) { \
  11     void *mptr; \
  12     mptr = malloc (Y); \
  13     if (mptr == 0) { \
  14         error (fdout, ERR_MALLOC); \
  15     } \
  16     X = mptr; \
  17 }
  18 
  19 #define ERR_MALLOC 1
  20 #define ERR_PIPE 2
  21 #define ERR_ARGS 3
  22 
  23 void error (int fd, int err) {
  24     write (fd, &err, sizeof(err));
  25     exit (1);
  26 }
  27     
  28 /* read the following off the pipefd 
  29  * - the ChildStuff struct
  30  * - the SpawnInfo struct
  31  * - the data strings for fields in ChildStuff
  32  * 
  33  * Also, the global fields xx_parentPath and xx_parentPathv
  34  * are initialised.
  35  */
  36 void initChildStuff (int fdin, int fdout, ChildStuff *c) {
  37     int n;
  38     int argvBytes, nargv, envvBytes, nenvv;
  39     int dirlen;
  40     char *buf;
  41     SpawnInfo sp;
  42     int bufsize, offset=0;
  43 
  44     if (xx_readFully (fdin, c, sizeof(*c)) == -1) {
  45         error (fdout, ERR_PIPE);
  46     }
  47 
  48     if (xx_readFully (fdin, &sp, sizeof(sp)) == -1) {
  49         error (fdout, ERR_PIPE);
  50     }
  51     bufsize = sp.argvBytes + sp.envvBytes + sp.dirlen +
  52               sp.parentPathLen + sp.parentPathvBytes;
  53 
  54     ALLOC(buf, bufsize);
  55 
  56     if (xx_readFully (fdin, buf, bufsize) == -1) {
  57         error (fdout, ERR_PIPE);
  58     }
  59 
  60     /* Initialize argv[] */
  61     ALLOC(c->argv, sizeof(char *) * sp.nargv);
  62     xx_initVectorFromBlock (c->argv, buf+offset, sp.nargv-1);
  63     offset += sp.argvBytes;
  64 
  65     /* Initialize envv[] */
  66     if (sp.nenvv == 0) {
  67         c->envv = 0;
  68     } else {
  69         ALLOC(c->envv, sizeof(char *) * sp.nenvv);
  70         xx_initVectorFromBlock (c->envv, buf+offset, sp.nenvv-1);
  71         offset += sp.envvBytes;
  72     }
  73 
  74     /* Initialize pdir */
  75     if (sp.dirlen == 0) {
  76         c->pdir = 0;
  77     } else {
  78         c->pdir = buf+offset;
  79         offset += sp.dirlen;
  80     }
  81 
  82     /* Initialize xx_parentPath */
  83     xx_parentPath = buf+offset;
  84     offset += sp.parentPathLen;
  85 
  86     /* Initialize xx_parentPathv[] */
  87     ALLOC(xx_parentPathv, sizeof (char *) * sp.nparentPathv)
  88     xx_initVectorFromBlock (xx_parentPathv, buf+offset, sp.nparentPathv-1);
  89     offset += sp.parentPathvBytes;
  90 }
  91 
  92 int main(int argc, char *argv[]) {
  93     ChildStuff c;
  94     int t;
  95 
  96     /* argv[0] contains the fd number to read all the child info */
  97     int r, fdin, fdout;
  98 
  99     r = sscanf (argv[argc-1], "%d:%d", &fdin, &fdout);
 100     if (r != 2 || fcntl(fdin, F_GETFD) == -1) {
 101         /* can't report back in this case */
 102         fprintf(stdout, "This command is not for general use and should ");
 103         fprintf(stdout, "only be run as the result of a call to\n");
 104         fprintf(stdout, "ProcessBuilder.start() or Runtime.exec() in a java ");
 105         fprintf(stdout, "application\n");
 106         _exit(1);
 107     }
 108     initChildStuff (fdin, fdout, &c);
 109 
 110     xx_childProcess (&c);
 111     return 0; /* NOT REACHED */
 112 }