1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * University Copyright- Copyright (c) 1982, 1986, 1988 28 * The Regents of the University of California 29 * All Rights Reserved 30 * 31 * University Acknowledgment- Portions of this document are derived from 32 * software developed by the University of California, Berkeley, and its 33 * contributors. 34 */ 35 36 /* 37 * mailx -- a modified version of a University of California at Berkeley 38 * mail program 39 * 40 * npopen() and npclose() 41 * 42 * stolen from C library, modified to use SHELL variable 43 */ 44 45 46 #include <stdio.h> 47 #include <signal.h> 48 #include <fcntl.h> 49 50 #define tst(a,b) (*mode == 'r'? (b) : (a)) 51 #define RDR 0 52 #define WTR 1 53 54 #ifdef VMUNIX 55 #define sigset signal 56 #else 57 extern void (*sigset())(); 58 #endif 59 #ifdef preSVr4 60 extern FILE *fdopen(); 61 extern int execlp(), fork(), pipe(), close(), fcntl(); 62 #ifndef sun 63 typedef int pid_t; 64 #endif 65 #else 66 # include <unistd.h> 67 # include <wait.h> 68 #endif 69 static pid_t popen_pid[20]; 70 71 FILE * 72 npopen(char *cmd, char *mode) 73 { 74 int p[2]; 75 register pid_t pid; 76 register int myside, yourside; 77 char *Shell, *value(char *); 78 79 if ((Shell = value("SHELL")) == NULL || *Shell=='\0') 80 #ifdef preSVr4 81 Shell = "/bin/sh"; 82 #else 83 Shell = "/usr/bin/sh"; 84 #endif 85 if(pipe(p) < 0) 86 return(NULL); 87 myside = tst(p[WTR], p[RDR]); 88 yourside = tst(p[RDR], p[WTR]); 89 if((pid = fork()) == 0) { 90 /* myside and yourside reverse roles in child */ 91 int stdio; 92 93 stdio = tst(0, 1); 94 (void) close(myside); 95 (void) close(stdio); 96 (void) fcntl(yourside, 0, stdio); 97 (void) close(yourside); 98 (void) execlp(Shell, Shell, "-c", cmd, (char *)0); 99 perror(Shell); 100 _exit(1); 101 } 102 if(pid == (pid_t)-1) 103 return(NULL); 104 popen_pid[myside] = pid; 105 (void) close(yourside); 106 return(fdopen(myside, mode)); 107 } 108 109 int 110 npclose(FILE *ptr) 111 { 112 register int f; 113 register pid_t r; 114 int status; 115 void (*istat)(int), (*qstat)(int); 116 117 f = fileno(ptr); 118 (void) fclose(ptr); 119 istat = sigset(SIGINT, SIG_IGN); 120 qstat = sigset(SIGQUIT, SIG_IGN); 121 while((r = wait(&status)) != popen_pid[f] && r != (pid_t)-1) 122 ; 123 if(r == (pid_t)-1) 124 status = -1; 125 (void) sigset(SIGINT, istat); 126 (void) sigset(SIGQUIT, qstat); 127 return(status); 128 } 129