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 }