| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | #include "common.h" |
| | | #include "service.h" |
| | | #include <errno.h> |
| | | #include <fcntl.h> |
| | | #include <io.h> |
| | |
| | | HANDLE hStdout; /* stdout */ |
| | | HANDLE hStderr; /* stderr */ |
| | | |
| | | debug("Attempting to create child process '%s' background=%d.", command, |
| | | debug("createChildProcess: Attempting to create child process '%s' background=%d.", |
| | | command, |
| | | background); |
| | | |
| | | // reset process info first |
| | |
| | | |
| | | if (createOk) |
| | | { |
| | | debug("Successfully created child process '%s'.", command); |
| | | debug("createChildProcess: Successfully created child process '%s'.", command); |
| | | } |
| | | else |
| | | { |
| | | debugError("Failed to create child process '%s'. Last error = %d.", |
| | | debugError( |
| | | "createChildProcess: Failed to create child process '%s'. Last error = %d.", |
| | | command, GetLastError()); |
| | | } |
| | | |
| | | return createOk; |
| | | } // createChildProcess |
| | | |
| | | BOOL createBatchFileChildProcess(char* batchFile, BOOL background, |
| | | PROCESS_INFORMATION* procInfo) |
| | | { |
| | | BOOL createOk; |
| | | STARTUPINFO startInfo; // info to pass to the new process |
| | | DWORD processFlag; // background process flag |
| | | HANDLE hStdin; /* stdin */ |
| | | HANDLE hStdout; /* stdout */ |
| | | HANDLE hStderr; /* stderr */ |
| | | char command[COMMAND_SIZE]; // full command line |
| | | |
| | | if (strlen(batchFile) + 3 >= COMMAND_SIZE) |
| | | { |
| | | debug("createBatchFileChildProcess: the batch file path is too long."); |
| | | return FALSE; |
| | | } |
| | | sprintf(command, "/c %s", batchFile); |
| | | debug("createBatchFileChildProcess: Attempting to create child process '%s' background=%d.", |
| | | command, |
| | | background); |
| | | |
| | | // reset process info first |
| | | ZeroMemory(procInfo, sizeof(PROCESS_INFORMATION)); |
| | | |
| | | // initialize handles to pass to the child process |
| | | ZeroMemory(&startInfo, sizeof(STARTUPINFO)); |
| | | startInfo.cb = sizeof(STARTUPINFO); |
| | | startInfo.dwFlags |= STARTF_USESTDHANDLES; // use handles above |
| | | |
| | | hStdin= GetStdHandle(STD_INPUT_HANDLE); |
| | | SetHandleInformation (hStdin, HANDLE_FLAG_INHERIT, FALSE); |
| | | hStdout = GetStdHandle(STD_OUTPUT_HANDLE); |
| | | SetHandleInformation (hStdout, HANDLE_FLAG_INHERIT, FALSE); |
| | | hStderr = GetStdHandle(STD_ERROR_HANDLE); |
| | | SetHandleInformation (hStderr, HANDLE_FLAG_INHERIT, FALSE); |
| | | |
| | | // Create the child process |
| | | processFlag = background == TRUE ? DETACHED_PROCESS : 0; |
| | | createOk = CreateProcess( |
| | | "cmd.exe", // application name |
| | | command, // command line |
| | | NULL, // process security attributes |
| | | NULL, // primary thread security attributes |
| | | TRUE, // handles are inherited |
| | | processFlag, // creation flags |
| | | NULL, // use parent's environment |
| | | NULL, // use parent's current directory |
| | | &startInfo, // STARTUPINFO pointer |
| | | procInfo // receives PROCESS_INFORMATION |
| | | ); |
| | | |
| | | if (createOk) |
| | | { |
| | | debug("createBatchFileChildProcess: Successfully created child process '%s'.", command); |
| | | } |
| | | else |
| | | { |
| | | debugError("createBatchFileChildProcess: Failed to create child process '%s'. Last error = %d.", |
| | | command, GetLastError()); |
| | | } |
| | | |
| | | return createOk; |
| | | } // createChildProcess |
| | | |
| | | |
| | | // ---------------------------------------------------- |
| | | // Function used to launch a process for the given command |
| | | // If the process could be created it returns the pid of |
| | | // the created process and -1 otherwise. |
| | | // ---------------------------------------------------- |
| | | int spawn(const char* command, BOOL background) |
| | | int spawn(char* command, BOOL background) |
| | | { |
| | | DWORD childPid = -1; // child's pid |
| | | PROCESS_INFORMATION procInfo; // info on the new process |
| | | BOOL createOk; |
| | | |
| | | createOk = createChildProcess((char*)command, background, &procInfo); |
| | | createOk = createChildProcess(command, background, &procInfo); |
| | | |
| | | if(createOk) |
| | | { |
| | |
| | | } |
| | | } // spawn |
| | | |
| | | |
| | | // ---------------------------------------------------- |
| | | // Function used to wait for a process. |
| | | // The passed waitTime parameter is maximum the time in milliseconds to wait. |
| | | // Returns TRUE if the process ended and updates the exitCode |
| | | // parameter with the return value of the process. |
| | | // Returns FALSE if the process did not end with the provided |
| | | // timeout and the error code returned by WaitForSingleObject |
| | | // in the provided exitCode value. |
| | | // ---------------------------------------------------- |
| | | BOOL waitForProcess(PROCESS_INFORMATION* procInfo, DWORD waitTime, |
| | | DWORD* exitCode) |
| | | { |
| | | BOOL returnValue = TRUE; |
| | | DWORD waitForSingleCode; |
| | | debug("waitForProcess: wait time is: %d", waitTime); |
| | | waitForSingleCode = WaitForSingleObject (procInfo->hProcess, waitTime); |
| | | if (waitForSingleCode == WAIT_OBJECT_0) |
| | | { |
| | | debug("waitForProcess: was successful"); |
| | | GetExitCodeProcess(procInfo->hProcess, exitCode); |
| | | debug("waitForProcess exitCode: %d", *exitCode); |
| | | } |
| | | else |
| | | { |
| | | returnValue = FALSE; |
| | | switch (waitForSingleCode) |
| | | { |
| | | case WAIT_FAILED: |
| | | debug("waitForProcess: Wait for process failed: %d", GetLastError()); |
| | | break; |
| | | case WAIT_TIMEOUT: |
| | | debug("waitForProcess: Process timed out."); |
| | | break; |
| | | default: |
| | | debug("waitForProcess: WaitForSingleObject returned %d", waitForSingleCode); |
| | | } |
| | | *exitCode = waitForSingleCode; |
| | | } |
| | | return returnValue; |
| | | } |
| | | // --------------------------------------------------- |
| | | // Debug utility. |
| | | // --------------------------------------------------- |