jdk/src/solaris/bin/jexec.c
author ohair
Tue, 25 May 2010 15:58:33 -0700
changeset 5506 202f599c92aa
parent 2 90ce3da70b43
child 7028 adadd244f506
permissions -rw-r--r--
6943119: Rebrand source copyright notices Reviewed-by: darcy, weijun
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     2
 * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
 * jexec for J2SE
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
 * jexec is used by the system to allow execution of JAR files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
 *    Essentially jexec needs to run java and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 *    needs to be a native ISA executable (not a shell script), although
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 *    this native ISA executable requirement was a mistake that will be fixed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 *    (<ISA> is sparc or i386 or amd64).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 *    When you execute a jar file, jexec is executed by the system as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 *      /usr/java/jre/lib/<ISA>/jexec -jar JARFILENAME
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 *    so this just needs to be turned into:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 *      /usr/java/jre/bin/java -jar JARFILENAME
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * Solaris systems (new 7's and all 8's) will be looking for jexec at:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 *      /usr/java/jre/lib/<ISA>/jexec
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * Older systems may need to add this to their /etc/system file:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 *      set javaexec:jexec="/usr/java/jre/lib/<ISA>/jexec"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 *     and reboot the machine for this to work.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * This source should be compiled as:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 *      cc -o jexec jexec.c
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * And jexec should be placed at the following location of the installation:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 *      <INSTALLATIONDIR>/jre/lib/<ISA>/jexec  (for Solaris)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 *      <INSTALLATIONDIR>/lib/jexec            (for Linux)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * NOTE: Unless <INSTALLATIONDIR> is the "default" JDK on the system
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 *       (i.e. /usr/java -> <INSTALLATIONDIR>), this jexec will not be
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 *       found.  The 1.2 java is only the default on Solaris 8 and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 *       on systems where the 1.2 packages were installed and no 1.1
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 *       java was found.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * NOTE: You must use 1.2 jar to build your jar files. The system
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 *       doesn't seem to pick up 1.1 jar files.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * NOTE: We don't need to set LD_LIBRARY_PATH here, even though we
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 *       are running the actual java binary because the java binary will
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 *       look for it's libraries through it's own runpath, which uses
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 *       $ORIGIN.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * NOTE: This jexec should NOT have any special .so library needs because
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 *       it appears that this executable will NOT get the $ORIGIN of jexec
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 *       but the $ORIGIN of the jar file being executed. Be careful to keep
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 *       this program simple and with no .so dependencies.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
#include <stdlib.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
#include <stdio.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
#include <unistd.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
#include <string.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
#include <limits.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
#include <errno.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
#ifdef __linux__
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
#  include <sys/types.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
#  include <sys/stat.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
#  include <fcntl.h>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
#  include "manifest_info.h"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
static const int CRAZY_EXEC = ENOEXEC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
static const int BAD_MAGIC  = ENOEXEC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
static const char * BAD_EXEC_MSG     = "jexec failed";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
static const char * CRAZY_EXEC_MSG   = "missing args";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
static const char * MISSING_JAVA_MSG = "can't locate java";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
#ifdef __linux__
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
static const char * BAD_PATHNAME_MSG = "invalid path";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
static const char * BAD_FILE_MSG     = "invalid file";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
static const char * BAD_MAGIC_MSG    = "invalid file (bad magic number)";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
static const char * UNKNOWN_ERROR    = "unknown error";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
/* Define a constant that represents the number of directories to pop off the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
 * current location to find the java binary */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
#ifdef __linux__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
static const int RELATIVE_DEPTH = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
#else /* Solaris */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
static const int RELATIVE_DEPTH = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
/* path to java after popping */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
static const char * BIN_PATH = "/bin/java";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
/* flag used when running JAR files */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
static const char * JAR_FLAG = "-jar";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
#ifdef __linux__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
/* largest possible size for a local file header */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
static const size_t CHUNK_SIZE = 65535;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
/* smallest possible size for a local file header */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
static const ssize_t MIN_SIZE = LOCHDR + 1 + 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
int main(int argc, const char * argv[]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
void errorExit(int error, const char * message);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
int getJavaPath(const char * path, char * buf, int depth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
#ifdef __linux__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
const char * isJar(const char * path);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
 * This is the main entry point.  This program (jexec) will attempt to execute
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
 * a JAR file by finding the Java program (java), relative to its own location.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
 * The exact location of the Java program depends on the platform, i.e.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
 *      <INSTALLATIONDIR>/jre/lib/<ISA>/jexec  (for Solaris)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
 *      <INSTALLATIONDIR>/lib/jexec            (for Linux JDK)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
 * Once the Java program is found, this program copies any remaining arguments
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
 * into another array, which is then used to exec the Java program.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
 * On Linux this program does some additional steps.  When copying the array of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
 * args, it is necessary to insert the "-jar" flag between arg[0], the program
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
 * name, and the original arg[1], which is presumed to be a path to a JAR file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
 * It is also necessary to verify that the original arg[1] really is a JAR file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
 * (These steps are unnecessary on Solaris because they are taken care of by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
 * the kernel.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
int main(int argc, const char * argv[]) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    /* We need to exec the original arguments using java, instead of jexec.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     * Also, for Linux, it is necessary to add the "-jar" argument between
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * the new arg[0], and the old arg[1].  To do this we will create a new
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     * args array. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    char          java[PATH_MAX + 1];    /* path to java binary  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    const char ** nargv = NULL;          /* new args array       */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    int           nargc = 0;             /* new args array count */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    int           argi  = 0;             /* index into old array */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    /* Make sure we have something to work with */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    if ((argc < 1) || (argv == NULL)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        /* Shouldn't happen... */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        errorExit(CRAZY_EXEC, CRAZY_EXEC_MSG);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    /* Get the path to the java binary, which is in a known position relative
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * to our current position, which is in argv[0]. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    if (getJavaPath(argv[argi++], java, RELATIVE_DEPTH) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        errorExit(errno, MISSING_JAVA_MSG);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    nargv = (const char **) malloc((argc + 2) * (sizeof (const char *)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
    nargv[nargc++] = java;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
#ifdef __linux__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    /* The "-jar" flag is already in the original args list on Solaris,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     * so it only needs to be added on Linux. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    nargv[nargc++] = JAR_FLAG;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    if (argc >= 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        const char * jarfile = argv[argi++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        const char * message = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
#ifdef __linux__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        /* On Linux we also need to make sure argv[1] is really a JAR
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
         * file (this will also resolve any symlinks, which helps). */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        char jarPath[PATH_MAX + 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        if (realpath(jarfile, jarPath) == NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            errorExit(errno, BAD_PATHNAME_MSG);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
        message = isJar(jarPath);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        if (message != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            errorExit(errno, message);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        jarfile = jarPath;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
#endif
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        /* the next argument is the path to the JAR file */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        nargv[nargc++] = jarfile;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    /* finally copy any remaining arguments */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    while (argi < argc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        nargv[nargc++] = argv[argi++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    /* finally add one last terminating null */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    nargv[nargc++] = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    /* It's time to exec the java binary with the new arguments.  It
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
     * is possible that we've reached this point without actually
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
     * having a JAR file argument (i.e. if argc < 2), but we still
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     * want to exec the java binary, since that will take care of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     * displaying the correct usage. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    execv(java, (char * const *) nargv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    /* If the exec worked, this process would have been replaced
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
     * by the new process.  So any code reached beyond this point
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
     * implies an error in the exec. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    free(nargv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    errorExit(errno, BAD_EXEC_MSG);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
 * Exit the application by setting errno, and writing a message.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
 * Parameters:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
 *     error   - errno is set to this value, and it is used to exit.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
 *     message - the message to write.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
void errorExit(int error, const char * message) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
    if (error != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        errno = error;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
        perror((message != NULL) ? message : UNKNOWN_ERROR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
    exit((error == 0) ? 0 : 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
 * Get the path to the java binary that should be relative to the current path.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
 * Parameters:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
 *     path  - the input path that the java binary that should be relative to.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
 *     buf   - a buffer of size PATH_MAX or greater that the java path is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
 *             copied to.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
 *     depth - the number of names to trim off the current path, including the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
 *             name of this program.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
 * Returns:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
 *     This function returns 0 on success; otherwise it returns the value of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
 *     errno.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
int getJavaPath(const char * path, char * buf, int depth) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    int result = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
    /* Get the full path to this program.  Depending on whether this is Solaris
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     * or Linux, this will be something like,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
     *     <FOO>/jre/lib/<ISA>/jexec  (for Solaris)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     *     <FOO>/lib/jexec            (for Linux)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    if (realpath(path, buf) != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        int count = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        /* Pop off the filename, and then subdirectories for each level of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
         * depth */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
        for (count = 0; count < depth; count++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
            *(strrchr(buf, '/')) = '\0';
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        /* Append the relative location of java, creating something like,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
         *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
         *     <FOO>/jre/bin/java  (for Solaris)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
         *     <FOO>/bin/java      (for Linux)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        strcat(buf, BIN_PATH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        /* Failed to get the path */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        result = errno;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    return (result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
#ifdef __linux__
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
/*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
 * Check if the given file is a JAR file.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
 * Parameters:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
 *     path  - the path to the file to check for JAR magic.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
 * Returns:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
 *     This function return NULL on success.  Otherwise, errno is set, and it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
 *     returns a message that indicates what caused the failure.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
const char * isJar(const char * path) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    const char * result = BAD_FILE_MSG;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
    int fd = open(path, O_RDONLY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    if (fd != -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        unsigned char buf[CHUNK_SIZE];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        ssize_t count = read(fd, buf, CHUNK_SIZE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
        if (count >= MIN_SIZE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            result = BAD_MAGIC_MSG;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            // be sure the file is at least a ZIP file
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            if (GETSIG(buf) == LOCSIG) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                off_t flen  = LOCNAM(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                off_t xlen  = LOCEXT(buf);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                off_t start = LOCHDR + flen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                off_t end   = start  + xlen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
                if (end <= count) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                    while (start < end) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                        off_t xhid  = SH(buf, start);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                        off_t xdlen = SH(buf, start + 2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                        start += 4 + xdlen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                        if (xhid == 0xcafe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                            // found the JAR magic
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                            result = NULL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
        if (result != NULL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            errno = BAD_MAGIC;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        close (fd);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
    return (result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
#endif