[Cmake-commits] [cmake-commits] king committed ProcessUNIX.c 1.83 1.84
cmake-commits at cmake.org
cmake-commits at cmake.org
Wed Jun 10 11:48:37 EDT 2009
Update of /cvsroot/CMake/CMake/Source/kwsys
In directory public:/mounts/ram/cvs-serv31713/Source/kwsys
Modified Files:
ProcessUNIX.c
Log Message:
ENH: Teach KWSys Process basic VMS support
This achieves basic process execution on OpenVMS. We use work-arounds
for different fork()/exec() behavior and a lack of select().
VMS emulates fork/exec using setjmp/longjmp to evaluate the child and
parent return cases from fork. Therefore both must be invoked from the
same function.
Since select() works only for sockets we use the BeOS-style polling
implementation. However, non-blocking reads on empty pipes cannot be
distinguished easily from the last read on a closed pipe. Therefore we
identify end of data by an empty read after the child terminates.
Index: ProcessUNIX.c
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/kwsys/ProcessUNIX.c,v
retrieving revision 1.83
retrieving revision 1.84
diff -C 2 -d -r1.83 -r1.84
*** ProcessUNIX.c 10 Jun 2009 15:46:21 -0000 1.83
--- ProcessUNIX.c 10 Jun 2009 15:48:34 -0000 1.84
***************
*** 68,71 ****
--- 68,77 ----
#endif
+ #if defined(__VMS)
+ # define KWSYSPE_VMS_NONBLOCK , O_NONBLOCK
+ #else
+ # define KWSYSPE_VMS_NONBLOCK
+ #endif
+
#if defined(KWSYS_C_HAS_PTRDIFF_T) && KWSYS_C_HAS_PTRDIFF_T
typedef ptrdiff_t kwsysProcess_ptrdiff_t;
***************
*** 101,105 ****
* without select().
*/
! #if !defined(__BEOS__)
# define KWSYSPE_USE_SELECT 1
#endif
--- 107,111 ----
* without select().
*/
! #if !defined(__BEOS__) && !defined(__VMS)
# define KWSYSPE_USE_SELECT 1
#endif
***************
*** 171,174 ****
--- 177,181 ----
kwsysProcessCreateInformation* si);
static void kwsysProcessKill(pid_t process_id);
+ static int kwsysProcessSetVMSFeature(char* name, int value);
static int kwsysProcessesAdd(kwsysProcess* cp);
static void kwsysProcessesRemove(kwsysProcess* cp);
***************
*** 721,724 ****
--- 728,738 ----
}
+ /* Make sure pipes behave like streams on VMS. */
+ if(!kwsysProcessSetVMSFeature("DECC$STREAM_PIPE", 1))
+ {
+ kwsysProcessCleanup(cp, 1);
+ return;
+ }
+
/* Save the real working directory of this process and change to
the working directory for the child processes. This is needed
***************
*** 760,764 ****
/* Create the pipe. */
int p[2];
! if(pipe(p) < 0)
{
kwsysProcessCleanup(cp, 1);
--- 774,778 ----
/* Create the pipe. */
int p[2];
! if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
{
kwsysProcessCleanup(cp, 1);
***************
*** 1186,1194 ****
{
/* We are done reading from this pipe. */
! kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
! --cp->PipesLeft;
}
else if (n < 0) /* error */
{
if((errno != EINTR) && (errno != EAGAIN))
{
--- 1200,1221 ----
{
/* We are done reading from this pipe. */
! #if defined(__VMS)
! if(!cp->CommandsLeft)
! #endif
! {
! kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
! --cp->PipesLeft;
! }
}
else if (n < 0) /* error */
{
+ #if defined(__VMS)
+ if(!cp->CommandsLeft)
+ {
+ kwsysProcessCleanupDescriptor(&cp->PipeReadEnds[i]);
+ --cp->PipesLeft;
+ }
+ else
+ #endif
if((errno != EINTR) && (errno != EAGAIN))
{
***************
*** 1567,1570 ****
--- 1594,1602 ----
/*--------------------------------------------------------------------------*/
+ #if defined(__VMS)
+ int decc$set_child_standard_streams(int fd1, int fd2, int fd3);
+ #endif
+
+ /*--------------------------------------------------------------------------*/
static int kwsysProcessCreate(kwsysProcess* cp, int prIndex,
kwsysProcessCreateInformation* si, int* readEnd)
***************
*** 1617,1621 ****
/* Create the pipe. */
int p[2];
! if(pipe(p) < 0)
{
return 0;
--- 1649,1653 ----
/* Create the pipe. */
int p[2];
! if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
{
return 0;
***************
*** 1675,1679 ****
--- 1707,1718 ----
/* Fork off a child process. */
+ #if defined(__VMS)
+ /* VMS needs vfork and execvp to be in the same function because
+ they use setjmp/longjmp to run the child startup code in the
+ parent! TODO: OptionDetach. */
+ cp->ForkPIDs[prIndex] = vfork();
+ #else
cp->ForkPIDs[prIndex] = kwsysProcessFork(cp, si);
+ #endif
if(cp->ForkPIDs[prIndex] < 0)
{
***************
*** 1683,1686 ****
--- 1722,1729 ----
if(cp->ForkPIDs[prIndex] == 0)
{
+ #if defined(__VMS)
+ /* Specify standard pipes for child process. */
+ decc$set_child_standard_streams(si->StdIn, si->StdOut, si->StdErr);
+ #else
/* Close the read end of the error reporting pipe. */
close(si->ErrorPipe[0]);
***************
*** 1712,1718 ****
--- 1755,1763 ----
/* Restore all default signal handlers. */
kwsysProcessRestoreDefaultSignalHandlers();
+ #endif
/* Execute the real process. If successful, this does not return. */
execvp(cp->Commands[prIndex][0], cp->Commands[prIndex]);
+ /* TODO: What does VMS do if the child fails to start? */
/* Failure. Report error to parent and terminate. */
***************
*** 1720,1723 ****
--- 1765,1773 ----
}
+ #if defined(__VMS)
+ /* Restore the standard pipes of this process. */
+ decc$set_child_standard_streams(0, 1, 2);
+ #endif
+
/* A child has been created. */
++cp->CommandsLeft;
***************
*** 2267,2273 ****
{
/* Create an intermediate process. */
- #ifdef __VMS
- #define fork vfork
- #endif
pid_t middle_pid = fork();
if(middle_pid < 0)
--- 2317,2320 ----
***************
*** 2438,2441 ****
--- 2485,2508 ----
/*--------------------------------------------------------------------------*/
+ #if defined(__VMS)
+ int decc$feature_get_index(char *name);
+ int decc$feature_set_value(int index, int mode, int value);
+ static int kwsysProcessSetVMSFeature(char* name, int value)
+ {
+ int i;
+ errno = 0;
+ i = decc$feature_get_index(name);
+ return i >= 0 && (decc$feature_set_value(i, 1, value) >= 0 || errno == 0);
+ }
+ #else
+ static int kwsysProcessSetVMSFeature(char* name, int value)
+ {
+ (void)name;
+ (void)value;
+ return 1;
+ }
+ #endif
+
+ /*--------------------------------------------------------------------------*/
/* Global set of executing processes for use by the signal handler.
This global instance will be zero-initialized by the compiler. */
***************
*** 2478,2482 ****
/* Create the pipe. */
int p[2];
! if(pipe(p) < 0)
{
return 0;
--- 2545,2549 ----
/* Create the pipe. */
int p[2];
! if(pipe(p KWSYSPE_VMS_NONBLOCK) < 0)
{
return 0;
More information about the Cmake-commits
mailing list