1/* 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26#include <errno.h> 27#include <fcntl.h> 28#include <stdio.h> 29#include <stdlib.h> 30#include <unistd.h> 31#include <sys/types.h> 32#include <sys/stat.h> 33 34#include "childproc.h" 35 36extern int errno; 37 38#define ALLOC(X,Y) { \ 39 void *mptr; \ 40 mptr = malloc (Y); \ 41 if (mptr == 0) { \ 42 error (fdout, ERR_MALLOC); \ 43 } \ 44 X = mptr; \ 45} 46 47#define ERR_MALLOC 1 48#define ERR_PIPE 2 49#define ERR_ARGS 3 50 51void error (int fd, int err) { 52 write (fd, &err, sizeof(err)); 53 exit (1); 54} 55 56void shutItDown() { 57 fprintf(stdout, "This command is not for general use and should "); 58 fprintf(stdout, "only be run as the result of a call to\n"); 59 fprintf(stdout, "ProcessBuilder.start() or Runtime.exec() in a java "); 60 fprintf(stdout, "application\n"); 61 _exit(1); 62} 63 64/* 65 * read the following off the pipefd 66 * - the ChildStuff struct 67 * - the SpawnInfo struct 68 * - the data strings for fields in ChildStuff 69 */ 70void initChildStuff (int fdin, int fdout, ChildStuff *c) { 71 int n; 72 int argvBytes, nargv, envvBytes, nenvv; 73 int dirlen; 74 char *buf; 75 SpawnInfo sp; 76 int bufsize, offset=0; 77 int magic; 78 int res; 79 80 res = readFully (fdin, &magic, sizeof(magic)); 81 if (res != 4 || magic != magicNumber()) { 82 error (fdout, ERR_PIPE); 83 } 84 85 if (readFully (fdin, c, sizeof(*c)) == -1) { 86 error (fdout, ERR_PIPE); 87 } 88 89 if (readFully (fdin, &sp, sizeof(sp)) == -1) { 90 error (fdout, ERR_PIPE); 91 } 92 93 bufsize = sp.argvBytes + sp.envvBytes + 94 sp.dirlen + sp.parentPathvBytes; 95 96 ALLOC(buf, bufsize); 97 98 if (readFully (fdin, buf, bufsize) == -1) { 99 error (fdout, ERR_PIPE); 100 } 101 102 /* Initialize argv[] */ 103 ALLOC(c->argv, sizeof(char *) * sp.nargv); 104 initVectorFromBlock (c->argv, buf+offset, sp.nargv-1); 105 offset += sp.argvBytes; 106 107 /* Initialize envv[] */ 108 if (sp.nenvv == 0) { 109 c->envv = 0; 110 } else { 111 ALLOC(c->envv, sizeof(char *) * sp.nenvv); 112 initVectorFromBlock (c->envv, buf+offset, sp.nenvv-1); 113 offset += sp.envvBytes; 114 } 115 116 /* Initialize pdir */ 117 if (sp.dirlen == 0) { 118 c->pdir = 0; 119 } else { 120 c->pdir = buf+offset; 121 offset += sp.dirlen; 122 } 123 124 /* Initialize parentPathv[] */ 125 ALLOC(parentPathv, sizeof (char *) * sp.nparentPathv) 126 initVectorFromBlock ((const char**)parentPathv, buf+offset, sp.nparentPathv-1); 127 offset += sp.parentPathvBytes; 128} 129 130int main(int argc, char *argv[]) { 131 ChildStuff c; 132 int t; 133 struct stat buf; 134 /* argv[0] contains the fd number to read all the child info */ 135 int r, fdin, fdout; 136 137 r = sscanf (argv[argc-1], "%d:%d", &fdin, &fdout); 138 if (r == 2 && fcntl(fdin, F_GETFD) != -1) { 139 fstat(fdin, &buf); 140 if (!S_ISFIFO(buf.st_mode)) 141 shutItDown(); 142 } else { 143 shutItDown(); 144 } 145 initChildStuff (fdin, fdout, &c); 146 147 childProcess (&c); 148 return 0; /* NOT REACHED */ 149} 150