2012-02-05 11:35:58 -05:00
|
|
|
/****************************************************************
|
|
|
|
* *
|
2012-03-24 14:06:46 -04:00
|
|
|
* Copyright 2001, 2012 Fidelity Information Services, Inc *
|
2012-02-05 11:35:58 -05:00
|
|
|
* *
|
|
|
|
* This source code contains the intellectual property *
|
|
|
|
* of its copyright holder(s), and is made available *
|
|
|
|
* under a license. If you do not know the terms of *
|
|
|
|
* the license, please stop and do not read further. *
|
|
|
|
* *
|
|
|
|
****************************************************************/
|
|
|
|
|
|
|
|
/* gtm_pipe.c
|
|
|
|
|
|
|
|
Parameters --
|
|
|
|
|
|
|
|
command : the command to be executed.
|
|
|
|
pt : type of the pipe (input or output)
|
|
|
|
|
|
|
|
Returns --
|
|
|
|
|
2012-03-24 14:06:46 -04:00
|
|
|
-1 : fork error
|
2012-02-05 11:35:58 -05:00
|
|
|
-2 : pipe() error
|
|
|
|
other : the file descriptor serving as one end of the pipe
|
|
|
|
*/
|
|
|
|
#include "mdef.h"
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
#include "gtm_fcntl.h"
|
|
|
|
#include "gtm_stat.h"
|
|
|
|
#include "gtm_stdio.h"
|
|
|
|
#include "gtm_unistd.h"
|
|
|
|
#include "gtm_stdlib.h"
|
|
|
|
|
|
|
|
#include "gtm_pipe.h"
|
|
|
|
#include "eintr_wrappers.h"
|
|
|
|
#include "gtmio.h"
|
|
|
|
|
|
|
|
GBLDEF uint4 pipe_child;
|
|
|
|
|
|
|
|
int gtm_pipe(char *command, pipe_type pt)
|
|
|
|
{
|
|
|
|
int pfd[2], child, parent;
|
|
|
|
int dup2_res, rc;
|
|
|
|
pid_t child_pid;
|
|
|
|
|
|
|
|
parent = (int)pt;
|
|
|
|
child = 1 - parent;
|
|
|
|
|
|
|
|
if (0 > pipe(pfd))
|
|
|
|
{
|
|
|
|
PERROR("pipe : ");
|
|
|
|
return -2;
|
|
|
|
}
|
2012-03-24 14:06:46 -04:00
|
|
|
if (-1 == (child_pid = fork())) /* BYPASSOK: we exit immediately, no FORK_CLEAN needed */
|
2012-02-05 11:35:58 -05:00
|
|
|
{
|
|
|
|
PERROR("fork : ");
|
|
|
|
return -1;
|
|
|
|
} else if (0 == child_pid)
|
|
|
|
{ /* child process */
|
|
|
|
CLOSEFILE_RESET(pfd[parent], rc); /* resets "pfd[parent]" to FD_INVALID */
|
|
|
|
DUP2(pfd[child], child, dup2_res);
|
|
|
|
CLOSEFILE_RESET(pfd[child], rc); /* resets "pfd[child]" to FD_INVALID */
|
|
|
|
/* We should have used exec instead of SYSTEM. Earlier it was followed by exit(0), which calls exit_handler.
|
|
|
|
* So both child and parent will do exit handling. This can make ref_cnt < 0, or, it can release semaphores,
|
|
|
|
* which we should not release until parent exists. So we just call _exit(0). Add the do nothing if to
|
|
|
|
* keep compiler happy since exiting anyway.
|
|
|
|
*/
|
|
|
|
if (-1 == SYSTEM(command));
|
|
|
|
_exit(0); /* just exit from here */
|
|
|
|
} else
|
|
|
|
{ /* parent process */
|
|
|
|
pipe_child = child_pid;
|
|
|
|
CLOSEFILE_RESET(pfd[child], rc); /* resets "pfd[child]" to FD_INVALID */
|
|
|
|
return pfd[parent];
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(FALSE);
|
|
|
|
/* It should never get here, just to keep compiler happy. */
|
|
|
|
return -3;
|
|
|
|
}
|