/* Define a constant that represents the number of directories to pop off the
* current location to find the java binary */ #ifdef __linux__ staticconstint RELATIVE_DEPTH = 2; #else/* Solaris */ staticconstint RELATIVE_DEPTH = 3; #endif
/* path to java after popping */ staticconstchar * BIN_PATH = "/bin/java";
/* flag used when running JAR files */ staticconstchar * JAR_FLAG = "-jar";
#ifdef __linux__ /* largest possible size for a local file header */ staticconst size_t CHUNK_SIZE = 65535;
/* smallest possible size for a local file header */ staticconst ssize_t MIN_SIZE = LOCHDR + 1 + 4; #endif
int main(int argc, constchar * argv[]); void errorExit(int error, constchar * message); int getJavaPath(constchar * path, char * buf, int depth); #ifdef __linux__ constchar * isJar(constchar * path); #endif
/* *Thisisthemainentrypoint.Thisprogram(jexec)willattempttoexecute *aJARfilebyfindingtheJavaprogram(java),relativetoitsownlocation. *TheexactlocationoftheJavaprogramdependsontheplatform,i.e. * *<INSTALLATIONDIR>/jre/lib/<ISA>/jexec(forSolaris) *<INSTALLATIONDIR>/lib/jexec(forLinuxJDK) * *OncetheJavaprogramisfound,thisprogramcopiesanyremainingarguments *intoanotherarray,whichisthenusedtoexectheJavaprogram. * *OnLinuxthisprogramdoessomeadditionalsteps.Whencopyingthearrayof *args,itisnecessarytoinsertthe"-jar"flagbetweenarg[0],theprogram *name,andtheoriginalarg[1],whichispresumedtobeapathtoaJARfile. *Itisalsonecessarytoverifythattheoriginalarg[1]reallyisaJARfile. *(ThesestepsareunnecessaryonSolarisbecausetheyaretakencareofby *thekernel.)
*/ int main(int argc, constchar * argv[]) { /* We need to exec the original arguments using java, instead of jexec. *Also,forLinux,itisnecessarytoaddthe"-jar"argumentbetween *thenewarg[0],andtheoldarg[1].Todothiswewillcreateanew
* args array. */ char java[PATH_MAX + 1]; /* path to java binary */ constchar ** nargv = NULL; /* new args array */ int nargc = 0; /* new args array count */ int argi = 0; /* index into old array */
size_t alen = 0; /* length of new array */
/* Make sure we have something to work with */ if ((argc < 1) || (argv == NULL)) { /* Shouldn't happen... */
errorExit(CRAZY_EXEC, CRAZY_EXEC_MSG);
}
/* Get the path to the java binary, which is in a known position relative
* to our current position, which is in argv[0]. */ if (getJavaPath(argv[argi++], java, RELATIVE_DEPTH) != 0) {
errorExit(errno, MISSING_JAVA_MSG);
}
alen = (argc + 2) * (sizeof (constchar *)); if (alen <= 0 || alen > INT_MAX / sizeof(char *)) {
errorExit(errno, BAD_ARG_MSG);
}
nargv = (constchar **) malloc(alen); if (nargv == NULL) {
errorExit(errno, MEM_FAILED_MSG);
}
nargv[nargc++] = java;
#ifdef __linux__ /* The "-jar" flag is already in the original args list on Solaris,
* so it only needs to be added on Linux. */
nargv[nargc++] = JAR_FLAG; #endif
#ifdef __linux__ /* On Linux we also need to make sure argv[1] is really a JAR
* file (this will also resolve any symlinks, which helps). */ char jarPath[PATH_MAX + 1];
if (realpath(jarfile, jarPath) == NULL) {
errorExit(errno, BAD_PATHNAME_MSG);
}
jarfile = jarPath; #endif /* the next argument is the path to the JAR file */
nargv[nargc++] = jarfile;
}
/* finally copy any remaining arguments */ while (argi < argc) {
nargv[nargc++] = argv[argi++];
}
/* finally add one last terminating null */
nargv[nargc++] = NULL;
/* It's time to exec the java binary with the new arguments. It *ispossiblethatwe'vereachedthispointwithoutactually *havingaJARfileargument(i.e.ifargc<2),butwestill *wanttoexecthejavabinary,sincethatwilltakecareof
* displaying the correct usage. */
execv(java, (char * const *) nargv);
/* If the exec worked, this process would have been replaced *bythenewprocess.Soanycodereachedbeyondthispoint
* implies an error in the exec. */
free(nargv);
errorExit(errno, BAD_EXEC_MSG); return0; // keep the compiler happy
}
/* *Getthepathtothejavabinarythatshouldberelativetothecurrentpath. * *Parameters: *path-theinputpaththatthejavabinarythatshouldberelativeto. *buf-abufferofsizePATH_MAXorgreaterthatthejavapathis *copiedto. *depth-thenumberofnamestotrimoffthecurrentpath,includingthe *nameofthisprogram. * *Returns: *Thisfunctionreturns0onsuccess;otherwiseitreturnsthevalueof *errno.
*/ int getJavaPath(constchar * path, char * buf, int depth) { int result = 0;
/* Get the full path to this program. Depending on whether this is Solaris *orLinux,thiswillbesomethinglike, * *<FOO>/jre/lib/<ISA>/jexec(forSolaris) *<FOO>/lib/jexec(forLinux)
*/ if (realpath(path, buf) != NULL) { int count = 0;
/* Pop off the filename, and then subdirectories for each level of
* depth */ for (count = 0; count < depth; count++) {
*(strrchr(buf, '/')) = '\0';
}
/* Append the relative location of java, creating something like, * *<FOO>/jre/bin/java(forSolaris) *<FOO>/bin/java(forLinux)
*/
strcat(buf, BIN_PATH);
} else { /* Failed to get the path */
result = errno;
}
if (end <= count) {
end -= 4; // make sure there are 4 bytes to read at start while (start <= end) {
off_t xhid = SH(buf, start);
off_t xdlen = SH(buf, start + 2);
start += 4 + xdlen; if (xhid == 0xcafe) { // found the JAR magic
result = NULL; break;
}
}
}
}
}
if (result != NULL) {
errno = BAD_MAGIC;
}
close (fd);
}
return (result);
} #endif
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet am 2026-10-01)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.