This is coproc.c in view mode; [Download] [Up]
/* * coproc.c - co-process fork * * Written by * Andre Fachat (a.fachat@physik.tu-chemnitz.de) * * Patches by * * This file is part of VICE, the Versatile Commodore Emulator. * See README for copyright notice. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA. * */ /* * This is modelled after some examples in Stevens, "Advanced Progamming * in the Unix environment", Addison Wesley. * * It simply opens two uni-directional pipes and forks a process to * use the pipes as bidirectional connection for the stdin/out of the * child. * This, however, implies that the child knows its being piped and _buffers_ * all stdio. To avoid that one has to open a pseudo terminal device, * which is too heavily system dependant to be included here. * Instead a wrapper like the program "pty" described in the book mentioned * above could be used. * * Technicalities: It does not store the PID of the forked child but * instead it relies on the child being killed when the parent terminates * prematurely or the child terminates itself on EOF on stdin. * * The command string is given to "/bin/sh -c cmdstring" such that * the shell can do fileexpansion. * * We ignore all SIGCHLD and SIGPIPE signals that may occur here by * installing an ignoring handler. */ #include <sys/types.h> #include <stdio.h> #include <unistd.h> #include <errno.h> #include <signal.h> #include "vice.h" #include "coproc.h" #define SHELL "/bin/sh" /* HP-UX 9 fix */ #ifndef SA_RESTART #define SA_RESTART 0 #endif #ifndef NeXT static struct sigaction ignore; #endif int fork_coproc(int *fd_wr, int *fd_rd, char *cmd) { int fd1[2], fd2[2]; pid_t pid; #ifndef NeXT ignore.sa_handler = SIG_IGN; sigemptyset(&ignore.sa_mask); ignore.sa_flags = SA_NOCLDSTOP | SA_RESTART; sigaction(SIGCHLD, &ignore, NULL); sigaction(SIGPIPE, &ignore, NULL); #endif if(pipe(fd1) < 0) { fprintf(stderr,"Coproc: Couldn't open pipe!\n"); return -1; } if(pipe(fd2) < 0) { fprintf(stderr,"Coproc: Couldn't open pipe!\n"); close(fd1[0]); close(fd1[1]); return -1; } if( (pid = fork()) < 0) { fprintf(stderr,"Coproc: Couldn't fork()!\n"); close(fd1[0]); close(fd1[1]); close(fd2[0]); close(fd2[1]); return -1; } else if(pid==0) { /* child */ close(fd1[0]); if(fd1[1] != STDOUT_FILENO) { dup2(fd1[1], STDOUT_FILENO); close(fd1[1]); } close(fd2[1]); if(fd2[0] != STDIN_FILENO) { dup2(fd2[0], STDIN_FILENO); close(fd2[0]); } /* Hm, we have to close all other files that are currently * open now... */ execl(SHELL, "sh", "-c", cmd, NULL); exit(127); /* child dies on error */ } else { /* parent */ close(fd1[1]); close(fd2[0]); *fd_rd = fd1[0]; *fd_wr = fd2[1]; } return 0; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.