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

📄 pipe.c

📁 Gcomm is a serial communications program similar to seyon, but more modern, and easier to use. Works
💻 C
字号:
#ifndef lintstatic const char rcsid[] = "$Id: pipe.c,v 1.1.1.1 2001/03/08 00:01:47 efalk Exp $" ;#endif/* * Copyright (c) 1995 by Edward A. Falk *//********** * * *	@@@@    @@@   @@@@   @@@@@   *	@   @    @    @   @  @       *	@@@@     @    @@@@   @@@     *	@        @    @      @       *	@       @@@   @      @@@@@   * *	PIPE - Open connection to a program. * *	Routines provided here: * * *	PipeConnect() *		open pipe * *	PipeDisConnect() *		close pipe * * * *	Edward A. Falk * *	January, 1995 * * * **********/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <malloc.h>#include <string.h>#include <ctype.h>#include <fcntl.h>#include <errno.h>#include <sys/param.h>#include <sys/types.h>#include <sys/time.h>#include <sys/stat.h>#include <sys/stat.h>#include <sys/wait.h>#include <sys/signal.h>#include "gcomm.h"#include "winutils.h"extern	int	errno ;static	int	pid ;voidPipeConnect( char *programArgs ){	int	ifds[2], ofds[2] ;	char	*argv[128] ;	char	argstr[1024] ;	char	*optr, *ptr, **vptr ;	int	i,j ;	/* parse programArgs into argv */	programArgs = strdup( programArgs) ;	ptr = programArgs ;	optr = argstr ;	vptr = argv ;	while( isspace(*ptr) ) ++ptr ;	*vptr++ = optr ;	while( *ptr != '\0' )	{	  if( isspace(*ptr) )	/* blank */	  {	    *optr++ = '\0' ;	    while( isspace(*ptr) ) ++ptr ;	    if( *ptr != '\0' )	      *vptr++ = optr ;	  }	  else if( *ptr == '\''  ||	/* ' */		   *ptr == '"' )	/* " */	  {	    char q = *ptr++ ;	    while( *ptr != q && *ptr != '\0' )	      *optr++ = *ptr++ ;	    if( *ptr != '\0' )	      ++ptr ;	  }	  else if( *ptr == '\\' )	/* \ */	  {	    if( *++ptr != '\0' )	      *optr++ = *ptr++ ;	  }	  else	    *optr++ = *ptr++ ;	}	*optr = '\0' ;	*vptr = NULL ;	if( argv[0] == NULL ) {	  free( programArgs ) ;	  WindowStatus("Program name not specified") ;	  return ;	}	if( pipe(ifds) < 0 ) {	  free( programArgs ) ;	  WindowStatus("Cannot create pipe: %s", strerror(errno)) ;	  return ;	}	if( pipe(ofds) < 0 ) {	  close(ifds[0]) ;	  close(ifds[1]) ;	  free( programArgs ) ;	  WindowStatus("Cannot create pipe: %s", strerror(errno)) ;	  return ;	}	pid = vfork() ;	if( pid == -1 ) {	  close(ifds[0]) ;	  close(ifds[1]) ;	  close(ofds[0]) ;	  close(ofds[1]) ;	  free( programArgs ) ;	  WindowStatus("Cannot fork: %s", strerror(errno)) ;	  return ;	}	if( pid == 0 ) {	  /* Child, we write to ifds[1], read from ofds[0] */	  dup2(ofds[0],0) ;	/* stdin */	  dup2(ifds[1],1) ;	/* stdout */	  close(ifds[0]) ;	  close(ifds[1]) ;	  close(ofds[0]) ;	  close(ofds[1]) ;	  execvp(argv[0], argv) ;	  perror(argv[0]) ;	  _exit(127) ;	}	/* Parent.  We read from ifds[0], write to ofds[1] */	close(ifds[1]) ;	close(ofds[0]) ;	ifd = ifds[0] ;	ofd = ofds[1] ;	i = fcntl(ifd, F_GETFL, 0) ;	j = fcntl(ifd, F_SETFL, i|O_NDELAY) ;	i = fcntl(ofd, F_GETFL, 0) ;	j = fcntl(ofd, F_SETFL, i|O_NDELAY) ;	connectionActive = True ;	connectTime0 = time(NULL) ;	free( programArgs ) ;	WindowStatus("Connected") ;}static	intwait_for_sig(int pid, int wtime){	struct timeval timeout ;	int	i, status ;	timeout.tv_sec = wtime ;	timeout.tv_usec = 0 ;	if( (i=waitpid(pid, &status, WNOHANG)) > 0 ) 	  return i ;#ifdef	COMMENT	oldmask = sigsetmask(~sigmask(SIGCHLD)) ; /* block all but SIGCHLD */#endif	/* COMMENT */	i = select(0,NULL,NULL,NULL, &timeout) ;	if( i == -1 && errno != EINTR )	  perror("breakPipeConnection: select") ;	return waitpid(pid, &status, WNOHANG) ;}voidPipeDisConnect(){	int	status ;	int	i ;	/* first, block SIGCHLD so we don't get confused */#ifdef	COMMENT	oldmask = sigblock(sigmask(SIGCHLD)) ;#endif	/* COMMENT */	close(ifd) ;	close(ofd) ;	/* see if process has already exited */	i = waitpid(pid, &status, WNOHANG) ;	if( i <= 0 ) {	  /* we'll wait 10 seconds for it */	  WindowStatus("Waiting for child process to exit...") ;	  i = wait_for_sig(pid, 10) ;	  if( i <= 0 ) {	    WindowStatus("Sending SIGTERM to child process...") ;	    if( kill(pid, SIGTERM) < 0 )	      perror("breakPipeConnection: select") ;	    i = wait_for_sig(pid, 10) ;	    if( i <= 0 ) {	      WindowStatus("Sending SIGKILL to child process...") ;	      if( kill(pid, SIGKILL) < 0 )		perror("breakPipeConnection: select") ;	      i = wait_for_sig(pid, 10) ;	      if( i <= 0 )		WindowStatus( "Warning, process %d wouldn't die", pid) ;	    }	  }	}#ifdef	COMMENT	(void) sigsetmask(oldmask) ;#endif	/* COMMENT */	ifd = ofd = -1 ;	ConnectionDone() ;}

⌨️ 快捷键说明

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