1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
|
/****************************************************************
* *
* Copyright (c) 2001-2015 Fidelity National Information *
* Services, Inc. and/or its subsidiaries. All rights reserved. *
* *
* 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 --
-1 : fork error
-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"
#include "fork_init.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;
}
FORK(child_pid);
if (-1 == child_pid)
{
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(EXIT_SUCCESS), 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 UNDERSCORE_EXIT(EXIT_SUCCESS).
*/
rc = SYSTEM(command);
UNDERSCORE_EXIT(EXIT_SUCCESS); /* 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];
}
}
|