⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pipeline.c

📁 早期freebsd实现
💻 C
字号:
/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.     Written by James Clark (jjc@jclark.com)This file is part of groff.groff is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.groff is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public License alongwith groff; see the file COPYING.  If not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA. *//*Compile options are:-DWCOREFLAG=0200 (or whatever)-DHAVE_VFORK_H-Dvfork=fork-DHAVE_SYS_SIGLIST-DHAVE_UNISTD_H*/#include <stdio.h>#include <signal.h>#include <errno.h>#include <sys/types.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_VFORK_H#include <vfork.h>#endif#ifndef errnoextern int errno;#endifextern char *strerror();#ifdef _POSIX_VERSION#include <sys/wait.h>#define PID_T pid_t#else /* not _POSIX_VERSION *//* traditional Unix */#define WIFEXITED(s) (((s) & 0377) == 0)#define WIFSTOPPED(s) (((s) & 0377) == 0177)#define WIFSIGNALED(s) (((s) & 0377) != 0 && (((s) & 0377) != 0177))#define WEXITSTATUS(s) (((s) >> 8) & 0377)#define WTERMSIG(s) ((s) & 0177)#define WSTOPSIG(s) (((s) >> 8) & 0377)#ifndef WCOREFLAG#define WCOREFLAG 0200#endif#define PID_T int#endif /* not _POSIX_VERSION *//* SVR4 uses WCOREFLG; Net 2 uses WCOREFLAG. */#ifndef WCOREFLAG#ifdef WCOREFLG#define WCOREFLAG WCOREFLG#endif /* WCOREFLG */#endif /* not WCOREFLAG */#ifndef WCOREDUMP#ifdef WCOREFLAG#define WCOREDUMP(s) ((s) & WCOREFLAG)#else /* not WCOREFLAG */#define WCOREDUMP(s) (0)#endif /* WCOREFLAG */#endif /* not WCOREDUMP */#include "pipeline.h"#ifdef __STDC__#define P(parms) parms#else#define P(parms) ()#endif#define error c_errorextern void error P((char *, char *, char *, char *));static void sys_fatal P((char *));static char *strsignal P((int));static char *itoa P((int));int run_pipeline(ncommands, commands)     int ncommands;     char ***commands;{  int i;  int last_input = 0;  PID_T pids[MAX_COMMANDS];  int ret = 0;  int proc_count = ncommands;  for (i = 0; i < ncommands; i++) {      int pdes[2];      PID_T pid;      if (i != ncommands - 1) {	if (pipe(pdes) < 0)	  sys_fatal("pipe");      }      pid = vfork();      if (pid < 0)	sys_fatal("fork");      if (pid == 0) {	/* child */	if (last_input != 0) {	  if (close(0) < 0)	    sys_fatal("close");	  if (dup(last_input) < 0)	    sys_fatal("dup");	  if (close(last_input) < 0)	    sys_fatal("close");	}	if (i != ncommands - 1) {	  if (close(1) < 0)	    sys_fatal("close");	  if (dup(pdes[1]) < 0)	    sys_fatal("dup");	  if (close(pdes[1]) < 0)	    sys_fatal("close");	  if (close(pdes[0]))	    sys_fatal("close");	}	execvp(commands[i][0], commands[i]);	error("couldn't exec %1: %2", commands[i][0],	      strerror(errno), (char *)0);	fflush(stderr);		/* just in case error() doesn't */	_exit(EXEC_FAILED_EXIT_STATUS);      }      /* in the parent */      if (last_input != 0) {	if (close(last_input) < 0)	  sys_fatal("close");      }      if (i != ncommands - 1) {	if (close(pdes[1]) < 0)	  sys_fatal("close");	last_input = pdes[0];      }      pids[i] = pid;    }  while (proc_count > 0) {    int status;    PID_T pid = wait(&status);    if (pid < 0)      sys_fatal("wait");    for (i = 0; i < ncommands; i++)      if (pids[i] == pid) {	pids[i] = -1;	--proc_count;	if (WIFSIGNALED(status)) {	  int sig = WTERMSIG(status);#ifdef SIGPIPE	  if (sig == SIGPIPE) {	    if (i == ncommands - 1) {	      /* This works around a problem that occurred when using the		 rerasterize action in gxditview.  What seemed to be		 happening (on SunOS 4.1.1) was that pclose() closed the		 pipe and waited for groff, gtroff got a SIGPIPE, but		 gpic blocked writing to gtroff, and so groff blocked		 waiting for gpic and gxditview blocked waiting for		 groff.  I don't understand why gpic wasn't getting a		 SIGPIPE. */	      int j;	      for (j = 0; j < ncommands; j++)		if (pids[j] > 0)		  (void)kill(pids[j], SIGPIPE);	    }	  }	  else#endif /* SIGPIPE */	  {	    error("%1: %2%3",		  commands[i][0],		  strsignal(sig),		  WCOREDUMP(status) ? " (core dumped)" : "");	    ret |= 2;	  }	}	else if (WIFEXITED(status)) {	  int exit_status = WEXITSTATUS(status);	  if (exit_status == EXEC_FAILED_EXIT_STATUS)	    ret |= 4;	  else if (exit_status != 0)	    ret |= 1;	}	else	  error("unexpected status %1",		itoa(status), (char *)0, (char *)0);	break;      }  }  return ret;}static void sys_fatal(s)     char *s;{  c_fatal("%1: %2", s, strerror(errno), (char *)0);}static char *itoa(n)     int n;{  static char buf[12];  sprintf(buf, "%d", n);  return buf;}static char *strsignal(n)     int n;{  static char buf[sizeof("Signal ") + 1 + sizeof(int)*3];#ifdef HAVE_SYS_SIGLIST  extern char *sys_siglist[];  if (n >= 0 && n < NSIG && sys_siglist[n] != 0)    return sys_siglist[n];#endif /* HAVE_SYS_SIGLIST */  sprintf(buf, "Signal %d", n);  return buf;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -