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