This is pipe.c in view mode; [Download] [Up]
/* * PCN System * Author: Steve Tuecke * Argonne National Laboratory * * Please see the DISCLAIMER file in the top level directory of the * distribution regarding the provisions under which this software * is distributed. * * pipe.c * * C code to setup and run a pipe. */ /* * Pipe input for PCN compiler to implement compilation directives -- * CAL Jan. 91 */ #include <stdio.h> #include <sys/types.h> #include <sys/signal.h> #include <sys/file.h> #include <sys/wait.h> #include <errno.h> #ifdef PCN_SYSV #include <sys/fcntl.h> #endif #include "pcn_pipe.h" #include "pcn_types.h" static char sh_path[] = "/bin/sh"; static char sh_arg1[] = "-c"; static char *exec_args[4] = {sh_path, sh_arg1, (char *) NULL, (char *) NULL}; #define PIPE_READ 0 #define PIPE_WRITE 1 /* #define DEBUG 1 */ /* * _p_pipe_setup_pipe() * * Use '/bin/sh -c command' to fork off a child with optional * stdin, stdout, and stderr. /bin/sh is used in order to get * reasonable argument handling. (For example, of quoted strings, * wildcards, etc.) */ _p_pipe_setup_pipe(command, stdin_action, fp_in, stdout_action, fp_out, stderr_action, fp_err, pid) char *command; int_t *stdin_action; FILE **fp_in; int_t *stdout_action; FILE **fp_out; int_t *stderr_action; FILE **fp_err; int_t *pid; { int pipe_in[2]; /* 0=reading, 1=writing */ int pipe_out[2]; int pipe_err[2]; int dev_null_fd = -1; int status; exec_args[2] = command; /* Setup stdin */ if (*stdin_action == STDIN_CREATE && pipe( pipe_out ) ) { perror("stdio_pipe"); *pid = -1; return; } /* Setup stdout */ if (*stdout_action == STDOUT_CREATE && pipe( pipe_out ) ) { perror("stdio_pipe"); *pid = -1; return; } /* Setup stderr */ if (*stderr_action == STDERR_CREATE && pipe( pipe_err ) ) { perror("stdio_pipe"); *pid = -1; return; } /* Fork */ *pid = (int_t) fork(); if ( *pid < 0 ) /* error */ { perror("stdio_pipe"); return; } if ( *pid > 0 ) /* parent */ { if (*stdin_action == STDIN_CREATE) { close( pipe_in[PIPE_READ] ); *fp_in = (FILE *) fdopen( pipe_in[PIPE_WRITE], "w" ); } if (*stdout_action == STDOUT_CREATE) { close( pipe_out[PIPE_WRITE] ); *fp_out = (FILE *) fdopen( pipe_out[PIPE_READ], "r" ); } if (*stderr_action == STDERR_CREATE) { close( pipe_err[PIPE_WRITE] ); *fp_err = (FILE *) fdopen( pipe_err[PIPE_READ], "r" ); } return; } else /* child */ { #if DEBUG > 0 char **argp; fprintf(stderr,"Child execing: "); argp = exec_args; while ( *argp != NULL ) fprintf(stderr," %s", *argp++); fprintf(stderr,"\n"); fflush(stderr); #endif if ( *stdin_action == STDIN_FROM_DEV_NULL || *stdout_action == STDOUT_TO_DEV_NULL || *stderr_action == STDERR_TO_DEV_NULL) { dev_null_fd = open("/dev/null", O_RDWR, 0); } else { dev_null_fd = -1; } /* Setup stdin */ if (*stdin_action == STDIN_FROM_DEV_NULL) { status = dup2( dev_null_fd, 0 ); } else if (*stdin_action == STDIN_CREATE) { close( pipe_in[PIPE_WRITE] ); status = dup2( pipe_in[PIPE_READ], 0 ); close( pipe_in[PIPE_READ] ); } else if(*stdin_action == STDIN_USE_ARGUMENT) { /* Feeding the fp argument to stdin */ status = dup2( fileno(*fp_in), 0 ); fclose(*fp_in); } /* Setup stdout */ if (*stdout_action == STDOUT_TO_DEV_NULL) { status = dup2( dev_null_fd, 1 ); } else if (*stdout_action == STDOUT_CREATE) { close( pipe_out[PIPE_READ] ); status = dup2( pipe_out[PIPE_WRITE], 1 ); close( pipe_out[PIPE_WRITE] ); } else if (*stdout_action == STDOUT_USE_ARGUMENT) { /* Feeding the fp argument to stdout */ status = dup2( fileno(*fp_out), 1 ); fclose(*fp_out); } /* Setup stderr */ if (*stderr_action == STDERR_TO_DEV_NULL) { status = dup2( dev_null_fd, 2 ); } else if (*stderr_action == STDERR_CREATE) { close( pipe_err[PIPE_READ] ); status = dup2( pipe_err[PIPE_WRITE], 2 ); close( pipe_err[PIPE_WRITE] ); } else if (*stderr_action == STDERR_USE_ARGUMENT) { /* Feeding the fp argument to stderr */ status = dup2( fileno(*fp_err), 2 ); fclose(*fp_err); } if (dev_null_fd >= 0) close( dev_null_fd ); status = execv( sh_path, exec_args ); perror("stdio_pipe"); exit(0); } } /* _p_pipe_setup_pipe() */ #if defined(next040) typedef union wait my_wait_t; #else typedef int my_wait_t; #endif /* * _p_pipe_wait() * * Wrapper around wait(), to wait for a child process to signal this process. * Fill in pid, exit_status, and signal with the appropriate values. * If block==1, then make it a blocking wait, otherwise make it a nonblocking * wait. */ _p_pipe_wait(pid, exit_status, signal, block) int_t *pid, *exit_status, *signal, *block; { #if defined(next040) || defined(iris) union wait status; #else int status; #endif int options; int status_int; int status_byte; if (*block) options = 0; else options = WNOHANG; *pid = (int_t) wait3(&status, options, (struct rusage *) 0); if (*pid <= 0) { *exit_status = -1; *signal = -1; } else { status_int = *((int *) &status); status_byte = status_int & 0xFF; if (status_byte == 0) { /* child process exited due to exit call -- get the exit status */ *exit_status = (int_t) ((status_int & 0xFF00) >> 8); *signal = -1; } else if (status_byte == 0177) { /* child process has stopped */ *exit_status = -1; *signal = -1; } else { /* child process terminated due to a signal -- get the signal */ *exit_status = -1; *signal = (int_t) (status_int & 0x7F); } } } /* _p_pipe_wait() */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.