version 1.9, 2007/11/28 12:44:18
|
version 1.10, 2008/02/05 19:59:40
|
|
|
#include <sys/stat.h> | #include <sys/stat.h> |
#include <unistd.h> | #include <unistd.h> |
#include <string.h> | #include <string.h> |
|
#include <signal.h> |
|
#include <time.h> |
#include "Config.h" | #include "Config.h" |
#include "Child.h" | #include "Child.h" |
#include "Parent.h" | #include "Parent.h" |
|
|
#include "Options.h" | #include "Options.h" |
#include <Pegasus/Common/PegasusVersion.h> | #include <Pegasus/Common/PegasusVersion.h> |
| |
|
#define CIMSERVER_COMMAND_TIMEOUT_SECONDS 240 |
|
|
/* | /* |
**============================================================================== | **============================================================================== |
** | ** |
|
|
{ | { |
const char* cimservermainPath; | const char* cimservermainPath; |
int pair[2]; | int pair[2]; |
|
int initCompletePipe[2]; |
|
int pid; |
char username[EXECUTOR_BUFFER_SIZE]; | char username[EXECUTOR_BUFFER_SIZE]; |
const char* childUserName; | const char* childUserName; |
int childUid; | int childUid; |
|
|
} | } |
} | } |
| |
/* Create a socket pair for communicating with the child process. */ |
|
|
|
if (CreateSocketPair(pair) != 0) |
|
Fatal(FL, "Failed to create socket pair"); |
|
|
|
CloseOnExec(pair[1]); |
|
|
|
/* Initialize the log-level from the configuration parameter. */ | /* Initialize the log-level from the configuration parameter. */ |
| |
InitLogLevel(); | InitLogLevel(); |
|
|
chdir("/"); | chdir("/"); |
#endif | #endif |
| |
|
/* Create a pipe for communicating with cimserver daemon process. */ |
|
|
|
if (pipe(initCompletePipe) != 0) |
|
Fatal(FL, "Failed to create pipe"); |
|
|
|
CloseOnExec(initCompletePipe[0]); |
|
CloseOnExec(initCompletePipe[1]); |
|
|
|
/* Fork to ensure we are not a session leader so setsid() will succeed. */ |
|
|
|
pid = fork(); |
|
|
|
if (pid < 0) |
|
{ |
|
Fatal(FL, "fork() failed"); |
|
} |
|
|
|
if (pid > 0) |
|
{ |
|
/* Wait until daemon writes an exit code or closes the pipe. */ |
|
|
|
char exitRC; |
|
ssize_t result; |
|
time_t startTime; |
|
time_t now; |
|
|
|
close(initCompletePipe[1]); |
|
SetNonBlocking(initCompletePipe[0]); |
|
time(&startTime); |
|
|
|
do |
|
{ |
|
time(&now); |
|
result = WaitForReadEnable( |
|
initCompletePipe[0], |
|
(CIMSERVER_COMMAND_TIMEOUT_SECONDS - (now - startTime)) * 1000); |
|
} while (result == -1 && errno == EINTR); |
|
|
|
if (result == 0) |
|
{ |
|
fprintf(stderr, |
|
"The cimserver command timed out waiting for the CIM server " |
|
"to start."); |
|
_exit(0); |
|
} |
|
|
|
EXECUTOR_RESTART(read(initCompletePipe[0], &exitRC, 1), result); |
|
if (result <= 0) |
|
{ |
|
exitRC = 1; |
|
} |
|
_exit(exitRC); |
|
} |
|
|
|
close(initCompletePipe[0]); |
|
|
|
/* Become session leader (so that our child process will not be one) */ |
|
|
|
if (setsid() < 0) |
|
{ |
|
Fatal(FL, "setsid() failed"); |
|
} |
|
|
|
/* Ignore SIGHUP: */ |
|
|
|
signal(SIGHUP, SIG_IGN); |
|
|
|
/* Ignore SIGCHLD: */ |
|
|
|
signal(SIGCHLD, SIG_IGN); |
|
|
|
/* Ignore SIGPIPE: */ |
|
|
|
signal(SIGPIPE, SIG_IGN); |
|
|
|
/* Fork cimserver daemon process (not a session leader since parent is). */ |
|
|
|
pid = fork(); |
|
|
|
if (pid < 0) |
|
{ |
|
Fatal(FL, "fork() failed"); |
|
} |
|
|
|
if (pid > 0) |
|
{ |
|
_exit(0); |
|
} |
|
|
/* Determine user for running CIMSERVERMAIN. */ | /* Determine user for running CIMSERVERMAIN. */ |
| |
GetServerUser(&childUserName, &childUid, &childGid); | GetServerUser(&childUserName, &childUid, &childGid); |
| |
|
/* Create a socket pair for communicating with the child process. */ |
|
|
|
if (CreateSocketPair(pair) != 0) |
|
Fatal(FL, "Failed to create socket pair"); |
|
|
|
CloseOnExec(pair[1]); |
|
|
/* Fork child process. */ | /* Fork child process. */ |
| |
childPid = fork(); | childPid = fork(); |
|
|
{ | { |
/* Parent. */ | /* Parent. */ |
close(pair[0]); | close(pair[0]); |
Parent(pair[1], childPid, options.bindVerbose); |
Parent(pair[1], initCompletePipe[1], childPid, options.bindVerbose); |
} | } |
else | else |
{ | { |