src/solaris/bin/jexec.c

Print this page


   1 /*
   2  * Copyright (c) 1999, 2012, 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


  73 #include <stdlib.h>
  74 #include <stdio.h>
  75 #include <unistd.h>
  76 #include <string.h>
  77 #include <limits.h>
  78 #include <errno.h>
  79 #ifdef __linux__
  80 #  include <sys/types.h>
  81 #  include <sys/stat.h>
  82 #  include <fcntl.h>
  83 #  include "jni.h"
  84 #  include "manifest_info.h"
  85 #endif
  86 
  87 static const int CRAZY_EXEC = ENOEXEC;
  88 static const int BAD_MAGIC  = ENOEXEC;
  89 
  90 static const char * BAD_EXEC_MSG     = "jexec failed";
  91 static const char * CRAZY_EXEC_MSG   = "missing args";
  92 static const char * MISSING_JAVA_MSG = "can't locate java";

  93 #ifdef __linux__
  94 static const char * BAD_PATHNAME_MSG = "invalid path";
  95 static const char * BAD_FILE_MSG     = "invalid file";
  96 static const char * BAD_MAGIC_MSG    = "invalid file (bad magic number)";
  97 #endif
  98 static const char * UNKNOWN_ERROR    = "unknown error";
  99 
 100 /* Define a constant that represents the number of directories to pop off the
 101  * current location to find the java binary */
 102 #ifdef __linux__
 103 static const int RELATIVE_DEPTH = 2;
 104 #else /* Solaris */
 105 static const int RELATIVE_DEPTH = 3;
 106 #endif
 107 
 108 /* path to java after popping */
 109 static const char * BIN_PATH = "/bin/java";
 110 
 111 /* flag used when running JAR files */
 112 static const char * JAR_FLAG = "-jar";


 139  *
 140  * Once the Java program is found, this program copies any remaining arguments
 141  * into another array, which is then used to exec the Java program.
 142  *
 143  * On Linux this program does some additional steps.  When copying the array of
 144  * args, it is necessary to insert the "-jar" flag between arg[0], the program
 145  * name, and the original arg[1], which is presumed to be a path to a JAR file.
 146  * It is also necessary to verify that the original arg[1] really is a JAR file.
 147  * (These steps are unnecessary on Solaris because they are taken care of by
 148  * the kernel.)
 149  */
 150 int main(int argc, const char * argv[]) {
 151     /* We need to exec the original arguments using java, instead of jexec.
 152      * Also, for Linux, it is necessary to add the "-jar" argument between
 153      * the new arg[0], and the old arg[1].  To do this we will create a new
 154      * args array. */
 155     char          java[PATH_MAX + 1];    /* path to java binary  */
 156     const char ** nargv = NULL;          /* new args array       */
 157     int           nargc = 0;             /* new args array count */
 158     int           argi  = 0;             /* index into old array */

 159 
 160     /* Make sure we have something to work with */
 161     if ((argc < 1) || (argv == NULL)) {
 162         /* Shouldn't happen... */
 163         errorExit(CRAZY_EXEC, CRAZY_EXEC_MSG);
 164     }
 165 
 166     /* Get the path to the java binary, which is in a known position relative
 167      * to our current position, which is in argv[0]. */
 168     if (getJavaPath(argv[argi++], java, RELATIVE_DEPTH) != 0) {
 169         errorExit(errno, MISSING_JAVA_MSG);
 170     }
 171 
 172     nargv = (const char **) malloc((argc + 2) * (sizeof (const char *)));



 173     nargv[nargc++] = java;
 174 
 175 #ifdef __linux__
 176     /* The "-jar" flag is already in the original args list on Solaris,
 177      * so it only needs to be added on Linux. */
 178     nargv[nargc++] = JAR_FLAG;
 179 #endif
 180 
 181     if (argc >= 2) {
 182         const char * jarfile = argv[argi++];
 183         const char * message = NULL;
 184 
 185 #ifdef __linux__
 186         /* On Linux we also need to make sure argv[1] is really a JAR
 187          * file (this will also resolve any symlinks, which helps). */
 188         char jarPath[PATH_MAX + 1];
 189 
 190         if (realpath(jarfile, jarPath) == NULL) {
 191             errorExit(errno, BAD_PATHNAME_MSG);
 192         }


   1 /*
   2  * Copyright (c) 1999, 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


  73 #include <stdlib.h>
  74 #include <stdio.h>
  75 #include <unistd.h>
  76 #include <string.h>
  77 #include <limits.h>
  78 #include <errno.h>
  79 #ifdef __linux__
  80 #  include <sys/types.h>
  81 #  include <sys/stat.h>
  82 #  include <fcntl.h>
  83 #  include "jni.h"
  84 #  include "manifest_info.h"
  85 #endif
  86 
  87 static const int CRAZY_EXEC = ENOEXEC;
  88 static const int BAD_MAGIC  = ENOEXEC;
  89 
  90 static const char * BAD_EXEC_MSG     = "jexec failed";
  91 static const char * CRAZY_EXEC_MSG   = "missing args";
  92 static const char * MISSING_JAVA_MSG = "can't locate java";
  93 static const char * BAD_ARG_MSG      = "incorrect number of arguments";
  94 #ifdef __linux__
  95 static const char * BAD_PATHNAME_MSG = "invalid path";
  96 static const char * BAD_FILE_MSG     = "invalid file";
  97 static const char * BAD_MAGIC_MSG    = "invalid file (bad magic number)";
  98 #endif
  99 static const char * UNKNOWN_ERROR    = "unknown error";
 100 
 101 /* Define a constant that represents the number of directories to pop off the
 102  * current location to find the java binary */
 103 #ifdef __linux__
 104 static const int RELATIVE_DEPTH = 2;
 105 #else /* Solaris */
 106 static const int RELATIVE_DEPTH = 3;
 107 #endif
 108 
 109 /* path to java after popping */
 110 static const char * BIN_PATH = "/bin/java";
 111 
 112 /* flag used when running JAR files */
 113 static const char * JAR_FLAG = "-jar";


 140  *
 141  * Once the Java program is found, this program copies any remaining arguments
 142  * into another array, which is then used to exec the Java program.
 143  *
 144  * On Linux this program does some additional steps.  When copying the array of
 145  * args, it is necessary to insert the "-jar" flag between arg[0], the program
 146  * name, and the original arg[1], which is presumed to be a path to a JAR file.
 147  * It is also necessary to verify that the original arg[1] really is a JAR file.
 148  * (These steps are unnecessary on Solaris because they are taken care of by
 149  * the kernel.)
 150  */
 151 int main(int argc, const char * argv[]) {
 152     /* We need to exec the original arguments using java, instead of jexec.
 153      * Also, for Linux, it is necessary to add the "-jar" argument between
 154      * the new arg[0], and the old arg[1].  To do this we will create a new
 155      * args array. */
 156     char          java[PATH_MAX + 1];    /* path to java binary  */
 157     const char ** nargv = NULL;          /* new args array       */
 158     int           nargc = 0;             /* new args array count */
 159     int           argi  = 0;             /* index into old array */
 160     size_t        alen  = 0;             /* length of new array */
 161 
 162     /* Make sure we have something to work with */
 163     if ((argc < 1) || (argv == NULL)) {
 164         /* Shouldn't happen... */
 165         errorExit(CRAZY_EXEC, CRAZY_EXEC_MSG);
 166     }
 167 
 168     /* Get the path to the java binary, which is in a known position relative
 169      * to our current position, which is in argv[0]. */
 170     if (getJavaPath(argv[argi++], java, RELATIVE_DEPTH) != 0) {
 171         errorExit(errno, MISSING_JAVA_MSG);
 172     }
 173     alen = (argc + 2) * (sizeof (const char *));
 174     if (alen <= 0 || alen > INT_MAX / sizeof(char *)) {
 175         errorExit(3, BAD_ARG_MSG);
 176     }
 177     nargv = (const char **) malloc(alen);
 178     nargv[nargc++] = java;
 179 
 180 #ifdef __linux__
 181     /* The "-jar" flag is already in the original args list on Solaris,
 182      * so it only needs to be added on Linux. */
 183     nargv[nargc++] = JAR_FLAG;
 184 #endif
 185 
 186     if (argc >= 2) {
 187         const char * jarfile = argv[argi++];
 188         const char * message = NULL;
 189 
 190 #ifdef __linux__
 191         /* On Linux we also need to make sure argv[1] is really a JAR
 192          * file (this will also resolve any symlinks, which helps). */
 193         char jarPath[PATH_MAX + 1];
 194 
 195         if (realpath(jarfile, jarPath) == NULL) {
 196             errorExit(errno, BAD_PATHNAME_MSG);
 197         }