ib_popen.c (2206B)
1 /* 2 * Copyright (c) 2003 Gunnar Ritter 3 * 4 * This software is provided 'as-is', without any express or implied 5 * warranty. In no event will the authors be held liable for any damages 6 * arising from the use of this software. 7 * 8 * Permission is granted to anyone to use this software for any purpose, 9 * including commercial applications, and to alter it and redistribute 10 * it freely, subject to the following restrictions: 11 * 12 * 1. The origin of this software must not be misrepresented; you must not 13 * claim that you wrote the original software. If you use this software 14 * in a product, an acknowledgment in the product documentation would be 15 * appreciated but is not required. 16 * 17 * 2. Altered source versions must be plainly marked as such, and must not be 18 * misrepresented as being the original software. 19 * 20 * 3. This notice may not be removed or altered from any source distribution. 21 */ 22 /* Sccsid @(#)ib_popen.c 1.2 (gritter) 4/17/03 */ 23 24 #include <sys/types.h> 25 #include <sys/stat.h> 26 #include <sys/wait.h> 27 #include <fcntl.h> 28 #include <unistd.h> 29 #include <string.h> 30 #include <errno.h> 31 #include <stdlib.h> 32 #include <signal.h> 33 34 #include "iblok.h" 35 36 struct iblok * 37 ib_popen(const char *cmd, unsigned blksize) 38 { 39 struct iblok *ip; 40 int fd[2], err; 41 pid_t pid; 42 char *shell; 43 44 if (pipe(fd) < 0) 45 return NULL; 46 switch (pid = fork()) { 47 case -1: 48 return NULL; 49 case 0: 50 close(fd[0]); 51 dup2(fd[1], 1); 52 close(fd[1]); 53 if ((shell = getenv("SHELL")) == NULL) 54 shell = "/bin/sh"; 55 execl(shell, shell, "-c", cmd, NULL); 56 _exit(0177); 57 /*NOTREACHED*/ 58 } 59 close(fd[1]); 60 if ((ip = ib_alloc(fd[0], blksize)) == NULL) { 61 err = errno; 62 close(fd[0]); 63 errno = err; 64 } 65 ip->ib_pid = pid; 66 return ip; 67 } 68 69 int 70 ib_pclose(struct iblok *ip) 71 { 72 struct sigaction oldhup, oldint, oldquit, act; 73 int status; 74 75 close(ip->ib_fd); 76 act.sa_handler = SIG_IGN; 77 sigemptyset(&act.sa_mask); 78 act.sa_flags = 0; 79 sigaction(SIGHUP, &act, &oldhup); 80 sigaction(SIGINT, &act, &oldint); 81 sigaction(SIGQUIT, &act, &oldquit); 82 while (waitpid(ip->ib_pid, &status, 0) < 0 && errno == EINTR); 83 sigaction(SIGHUP, &oldhup, NULL); 84 sigaction(SIGINT, &oldint, NULL); 85 sigaction(SIGQUIT, &oldquit, NULL); 86 return status; 87 }