in modules/samsa/src/main/native/samsa/samsa.c [111:379]
int main (int argc, char **argv, char **envp)
{
#if defined(WIN32)
PROCESS_INFORMATION procInfo;
STARTUPINFO startInfo;
#endif
int myArgvCount = argc;
int moreArgvCount = /* -cp <classpath> */ 2 + /* <tool-class> */ 1 + /* NULL */ 1;
char **myArgv = (char **) malloc(sizeof(char*) * (myArgvCount + moreArgvCount));
char *toolName = NULL;
char *cmd_line = NULL;
int size, i, j;
int cmd_len = 0;
int exit_code = -1;
int newIndex = 0;
char *root = NULL;
char *fullExePath = NULL;
TOOLDATA *pToolData = (TOOLDATA *) malloc(sizeof(TOOLDATA));
int isJavaw = 0;
int toolType = 0; /* 0 = JRE tool, 1 = JDK tool, 2 = JRE tool in jdk/bin */
/*
* get the root and the construct invocation path for exe
* and the full paths to jars. This way, we can be called
* from anywhere
*/
root = getRoot();
// printf("root = %s\n", root);
if (!root) {
fprintf(stderr, "Unable to find JRE/JDK Root");
return 2;
}
/*
* if we can't figure out what tool we are, just bail
*/
toolName = cleanToolName(argv[0]);
// printf("tool name = %s\n", toolName);
if (toolName == NULL) {
fprintf(stderr, "Unknown tool name %s\n", argv[0]);
return 1;
}
isJavaw = strcmp(toolName, "javaw") == 0;
toolType = getToolType(root, toolName);
if (toolType == -1) {
fprintf(stderr, "Unable to determine type (JDK/JRE) of tool\n");
return 1;
}
/*
* get the 'tool data' - right now, this is just the jars
* specificly needed by this tool
*/
pToolData = getToolData(toolName, root, toolType);
if (pToolData == NULL) {
return 2;
}
fullExePath = (char *) malloc(strlen(root) + strlen(JDK_WEXE_POSTFIX) + 1);
strcpy(fullExePath, root);
/*
* If we're javaw then we need to javaw to command line
*/
if (isJavaw) {
strcat(fullExePath, toolType ? JDK_WEXE_POSTFIX : JRE_WEXE_POSTFIX);
} else {
strcat(fullExePath, toolType ? JDK_EXE_POSTFIX : JRE_EXE_POSTFIX);
}
/*
* we're invoking java with the following
* -cp toolpath clasname .......
*/
myArgv[newIndex++] = fullExePath;
/*
* if we're not java or javaw, put the tools on cp, figure out the tool class to invoke...
*/
if (strcmp(toolName, "java") && !isJavaw) {
char *classpath;
char *buffer;
myArgvCount = argc + moreArgvCount;
// hangle non-empty -J<flag> options
for (i = 1; i < argc; i++) {
if (argv[i] != NULL && argv[i][0] == '-' && argv[i][1] == 'J' && argv[i][2] != '\0') {
myArgv[newIndex++] = argv[i] + 2;
}
}
size = strlen(root) * pToolData->numJars +
strlen(CLASSPATH_SEP) * (pToolData->numJars - 1) + 1;
for (i = 0; i < pToolData->numJars; i++) {
size += strlen(pToolData->jarList[i]);
}
classpath = (char *) malloc(size * sizeof(char));
strcpy(classpath, root);
strcat(classpath, pToolData->jarList[0]);
for (i = 1; i < pToolData->numJars; i++) {
strcat(classpath, CLASSPATH_SEP);
strcat(classpath, root);
strcat(classpath, pToolData->jarList[i]);
}
myArgv[newIndex++] = "-cp";
myArgv[newIndex++] = classpath;
buffer =
(char *) malloc(strlen(toolType==1 ? JDK_CLASS_PREFIX : JRE_CLASS_PREFIX)
+ strlen(toolName) + strlen(CLASS_POSTFIX) + 1);
strcpy(buffer, toolType==1 ? JDK_CLASS_PREFIX : JRE_CLASS_PREFIX);
strcat(buffer, toolName);
strcat(buffer, CLASS_POSTFIX);
myArgv[newIndex++] = buffer;
// copy remaining arguments (skipping -J options)
for (i = 1; i < argc; i++) {
if (argv[i] != NULL && argv[i][0] == '-' && argv[i][1] == 'J') continue;
myArgv[newIndex++] = argv[i];
}
} else {
// for 'java' wrappper copy all arguments without changes
for (i = 1; i < argc; i++) {
myArgv[newIndex++] = argv[i];
}
}
myArgv[newIndex] = NULL;
// for (i=0; i < myArgvCount; i++) {
// printf(" %d = %s\n", i, myArgv[i]);
// }
free(toolName);
/*
* now simply execv() the java app w/ the new params
*/
#if defined(WIN32)
/*
* win32 - CreateProcess() needs a cmd line string
* - double quote all arguments to avoid breaking spaces
* - prepend existing double quotes with '\'
*/
// determine required memory size for command line arguments
size = 0;
for (i=1; i < myArgvCount; i++) {
if (myArgv[i] != NULL) {
int arg_len = strlen(myArgv[i]);
size += /* space */ 1 + /* quotes */ 2 + arg_len;
for (j = 0; j < arg_len; j++) {
if (myArgv[i][j] == '\"') size++;
}
}
}
// allocate memory for whole command line
cmd_line = (char *) malloc(strlen(fullExePath) + /* quotes */ 2 + /* arguments */ size + /* NULL */ 1);
if (cmd_line == NULL) {
fprintf(stderr, "Unable to allocate memory for tool command line %s\n", argv[0]);
return 4;
}
// copy quoted exe path
sprintf(cmd_line, "\"%s\"", fullExePath);
cmd_len = strlen(cmd_line);
// copy quoted arguments and prepend existing double quotes with '\'
for (i=1; i < myArgvCount; i++) {
if (myArgv[i] != NULL) {
int arg_len = strlen(myArgv[i]);
cmd_line[cmd_len++] = ' '; // space delimiter
cmd_line[cmd_len++] = '\"'; // starting quote
for (j = 0; j < arg_len; j++) {
char ch = myArgv[i][j];
if (ch == '\"') {
cmd_line[cmd_len++] = '\\';
}
cmd_line[cmd_len++] = ch;
}
cmd_line[cmd_len++] = '\"'; // ending quote
}
}
cmd_line[cmd_len] = '\0';
// create child process
memset(&procInfo, 0, sizeof(PROCESS_INFORMATION));
memset(&startInfo, 0, sizeof(STARTUPINFO));
startInfo.cb = sizeof(STARTUPINFO);
if (!CreateProcess(NULL, cmd_line, NULL, NULL,
TRUE, 0, NULL, NULL, &startInfo, &procInfo)) {
fprintf(stderr, "Error creating process : %d\n", GetLastError());
free(cmd_line);
return exit_code;
}
free(cmd_line);
// wait for child process to finish
if (!isJavaw && WAIT_FAILED == WaitForSingleObject(procInfo.hProcess, INFINITE)) {
fprintf(stderr, "Error waiting for process : %d\n", GetLastError());
// terminate child process before exiting
if (!TerminateProcess(procInfo.hProcess, -1)) {
fprintf(stderr, "Error terminating process : %d\n", GetLastError());
}
}
else {
// get exit code of the finished child process
DWORD res = 0;
if (GetExitCodeProcess(procInfo.hProcess, &res)) {
exit_code = (int)res;
}
else {
fprintf(stderr, "Error getting process exit code : %d\n", GetLastError());
}
}
// close child process handles
CloseHandle(procInfo.hProcess);
CloseHandle(procInfo.hThread);
return exit_code;
#else
/*
* linux - use execv() to replace current process
*/
exit_code = execv(fullExePath, myArgv);
// execv returns here only in case of error
perror("Error creating process");
return exit_code;
#endif
}