/* spipe -- supervise a pipeline of programs * Copyright (C) 2000 Bruce Guenter * * 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 */ #include #include #include #include #include #include #include #include #include "bool.h" #include "svcfns.h" static unsigned part_count; static pid_t* part_pids; static int selfpipe[2]; static const char** part_names; void err(const char* msg) { fputs("spipe: Error: ", stderr); fputs(msg, stderr); fputc('\n', stderr); } void die(const char* msg) { err(msg); exit(1); } bool is_pipe(const char* p) { return p[0] == '|' && p[1] == 0; } void usage(const char* msg) { if(msg) err(msg); fputs("usage: spipe dir1 dir2 ...\n", stderr); exit(1); } void parse_args(int argc, char** argv) { --argc, ++argv; if(argc <= 0) usage("Too few command-line arguments"); part_count = argc; part_names = (const char**)argv; part_pids = calloc(part_count, sizeof(pid_t)); memset(part_pids, 0, sizeof(pid_t) * part_count); if(pipe(selfpipe)) die("Could not create self pipe"); } void stop_parts() { unsigned i; for(i = 0; i < part_count; i++) if(part_pids[i]) stop_supervise(part_names[i], part_pids[i]); } void start_parts() { int fdout = FD_STDOUT; int fdout_next = -1; unsigned i; for(i = part_count; i > 0; i--) { int fdin = FD_STDIN; if(i > 1) { int p[2]; if(pipe(p)) { die("Could not create pipe"); stop_parts(); exit(1); } fdin = p[0]; fdout_next = p[1]; } if(!start_supervise(part_names[i-1], fdin, fdout)) { stop_parts(); exit(1); } close(fdout); close(fdin); fdout = fdout_next; } } void handle_intr(int sig) { write(selfpipe[1], "", 1); } void mainloop() { char buf[1]; signal(SIGINT, handle_intr); signal(SIGQUIT, handle_intr); signal(SIGTERM, handle_intr); read(selfpipe[0], buf, 1); stop_parts(); exit(0); } int main(int argc, char** argv) { parse_args(argc, argv); start_parts(); mainloop(); return 0; }