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

📄 ecufork.c

📁 一个通讯程序源码
💻 C
字号:
/*+-------------------------------------------------------------------------	ecufork.c -- ecu spawning ground	wht@n4hgf.Mt-Park.GA.US  Defined functions:	exec_cmd(cmdstr)	expand_wildcard_list(wild,expcmd)	find_executable(progname)	is_executable(progname)	shell(shellcmd)	smart_fork()--------------------------------------------------------------------------*//*+:EDITS:*//*:09-10-1992-13:58-wht@n4hgf-ECU release 3.20 *//*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA *//*:04-29-1992-13:29-wht@n4hgf-ignore SIGQUIT when in executing a child *//*:09-25-1991-18:02-wht@n4hgf2-find_executable flunks directories now *//*:09-06-1991-04:20-wht@n4hgf2-expand_wildcard_list minor bug *//*:08-29-1991-01:56-wht@n4hgf2-use max esd size instead of 5120 *//*:07-25-1991-12:55-wht@n4hgf-ECU release 3.10 *//*:07-17-1991-07:04-wht@n4hgf-avoid SCO UNIX nap bug *//*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller *//*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */#include "ecu.h"#include "esd.h"#include "ecufork.h"extern int last_child_wait_status;extern int last_child_wait_pid;#ifdef M_I286#define MAX_EXEC_ARG 512#else#if defined(M_UNIX) || defined(ISC)#define MAX_EXEC_ARG 1024#else#define MAX_EXEC_ARG 2048#endif	/* M_UNIX || ISC */#endif	/* M_I286 *//*+-------------------------------------------------------------------------	smart_fork()--------------------------------------------------------------------------*/intsmart_fork(){	register int count = 5;	register int pid;	while(count--)	{		if((pid = fork()) >= 0)			return(pid);		if(count)			Nap(40L);	}	return(-1);}	/* end of smart_fork *//*+-----------------------------------------------------------------------	shell(shellcmd)  param 'shellcmd' is a shell command prefixed with either  a '!', '$', '>' character.  '!' causes the command to run as a normal subshell of a process.  '$' causes the communications line to be stdin and stdout      for the spawned shell  '>' causes spawned shell to receive exactly sames files as ecu------------------------------------------------------------------------*/voidshell(shellcmd)char *shellcmd;{	register shellpid;	register itmp;	register char *cptr;#if defined(FORK_DEBUG)	char s40[40];#endif	int wait_status;	int restart_rcvr = need_rcvr_restart();	char *getenv();	kill_rcvr_process(SIGUSR1);		/* stop receiver process gracefully */	signal(SIGINT,SIG_IGN);	signal(SIGQUIT,SIG_IGN);	signal(SIGUSR1,SIG_IGN);	signal(SIGUSR2,SIG_IGN);	signal(SIGCLD,SIG_DFL);	if((shellpid = smart_fork()) < 0)	{		ff(se,"Cannot fork\r\n");		if(restart_rcvr)			start_rcvr_process(1);		xmtr_signals();		return;	}	ttymode(0);  	     		/* set canonical tty mode */	if(shellpid == 0)			/* we are the spawned (going to call shell) */	{		if(*shellcmd != '>')	/* '>' prefix means leave fd's alone! */		{			/* Hook-up our "standard output" to either the tty or			 * the line as appropriate for '!' or '$' */			close(TTYOUT);			fcntl(((*shellcmd == '$') ? shm->Liofd : TTYERR),F_DUPFD,TTYOUT);			if(*shellcmd == '$')			{				close(TTYIN);				fcntl(shm->Liofd,F_DUPFD,TTYIN);			}			close(shm->Liofd);		}		child_signals();		/* signals for child */		if(*shellcmd == '!')		{			cptr = getenv("SHELL");			if(cptr == (char *)0)				cptr = "/bin/csh";		}		else			cptr = "/bin/sh";		shellcmd++;		child_signals();		if(ulindex(cptr,"csh") > -1)		{			if(*shellcmd == '\0')				execl(cptr,"csh",(char *)0);			else				execl(cptr,"csh","-c",shellcmd,(char *)0);		}		else		{			if(*shellcmd == '\0')				execl(cptr,"sh",(char *)0);			else				execl(cptr,"sh","-c",shellcmd,(char *)0);		}		ff(se,"cannot execute %s\r\n",cptr);	/* should not get here */		_exit(255);								/* end of spawned process */	}	/* end of if child process */#if defined(FORK_DEBUG)	sprintf(s40,"DEBUG fork shell pid %d",shellpid);	ecu_log_event(getpid(),s40); /* shell */#endif	while(((itmp = wait(&wait_status)) != shellpid) && (itmp != -1))		;	last_child_wait_status = wait_status;	last_child_wait_pid = shellpid;	xmtr_signals();			/* restore standard xmtr signals */	ttymode(1);				/* control tty back to raw mode *//* any comm program will probably doodle with the line characteristics. *//* we want to make sure they are restored to normal */	lreset_ksr();			/* restore comm line params */	if(restart_rcvr)		start_rcvr_process(1);}	/* end of shell *//*+-------------------------------------------------------------------------	is_executable(progname)--------------------------------------------------------------------------*/is_executable(progname)char *progname;{	struct stat ss;	if(stat(progname,&ss) < 0)			/* if cannot stat, flunk */		return(0);	if((ss.st_mode & 0111) == 0)		/* if no --x--x--x, flunk */		return(0);	if((ss.st_mode & S_IFMT) != S_IFREG)/* if no --x--x--x, flunk */		return(0);	return(1);	/* whew, this OUGHT to work */}	/* end of is_executable *//*+-------------------------------------------------------------------------	find_executable(progname)PATH=':/usr/wht/bin:/bin:/usr/bin:/usr/wht/bin:/etc/tuckerware' len=56--------------------------------------------------------------------------*/char *find_executable(progname)char *progname;{	register itmp;	static char *path_buf = (char *)0;#define PATHNAME_QUAN 32	static char *path_name[PATHNAME_QUAN + 1];	static char rtn_path[256];	static int path_count = 0;	char *cptr;	char *getenv();	if(path_buf == (char *)0)	{		if((cptr = getenv("PATH")) == (char *)0)			return(cptr);		if(!(path_buf = malloc(strlen(cptr) + 1)))			return((char *)0);		strcpy(path_buf,cptr);		path_name[PATHNAME_QUAN + 1] = (char *)0;		cptr = path_buf;		for(path_count = 0; path_count < PATHNAME_QUAN; path_count++)		{			if(*cptr == 0)				break;			path_name[path_count] = cptr;			while((*cptr != ':') && (*cptr != 0))				cptr++;			if(*cptr == ':')				*cptr++ = 0;		}	}	/* end of get and process path env variable *//* look for executable */	for(itmp = 0; itmp < path_count; itmp++)	{		if(*path_name[itmp] == 0)	/* if null path (./) */			strcpy(rtn_path,"./");		else			sprintf(rtn_path,"%s/",path_name[itmp]);		strcat(rtn_path,progname);		if(is_executable(rtn_path))			return(rtn_path);	}	return((char *)0);}	/* end of find_executable *//*+-------------------------------------------------------------------------	exec_cmd(cmdstr) - execute an arbitrary program with argumentskills rcvr process if alive and restarts it when done if was alive--------------------------------------------------------------------------*/exec_cmd(cmdstr)char *cmdstr;{	char *cmdpath;	char *cmdargv[MAX_EXEC_ARG];	int itmp;	int execpid;	int restart_rcvr = need_rcvr_restart();	int old_ttymode = get_ttymode();	int wait_status = 0;	char *strrchr();#if defined(FORK_DEBUG)	char s80[80];	strcpy(s80,"DEBUG exec ");	strncat(s80,cmdstr,sizeof(s80)-12);	s80[sizeof(s80)-12] = 0;	ecu_log_event(getpid(),s80);#endif	build_arg_array(cmdstr,cmdargv,MAX_EXEC_ARG,&itmp);	if(itmp == MAX_EXEC_ARG)	{		ff(se,"Too many arguments to command\r\n");		return(-1);	}	else if(!itmp)	{		ff(se,"null command\r\n");		return(-1);	}	if(*cmdargv[0] == '/')	{		cmdpath = cmdargv[0];		cmdargv[0] = strrchr(cmdargv[0],'/') + 1;	}	else	{		if((cmdpath = find_executable(cmdargv[0])) == (char *)0)		{			ff(se,"Cannot find %s\r\n",cmdargv[0]);			return(-1);		}	}	kill_rcvr_process(SIGUSR1);		/* stop receiver process gracefully *//* this code executed by the father (forking) process *//* wait on death of child (morbid in life, but ok here) */	signal(SIGINT,SIG_IGN);	signal(SIGQUIT,SIG_IGN);	signal(SIGUSR1,SIG_IGN);	signal(SIGUSR2,SIG_IGN);	signal(SIGCLD,SIG_DFL);	if((execpid = smart_fork()) < 0)	{		ff(se,"Cannot fork\r\n");		if(restart_rcvr)			start_rcvr_process(1);		xmtr_signals();		return(-1);	}	if(execpid == 0)			/* we are the spawned (going to call exec) */	{		ttymode(0);  	     	/* set canonical tty mode */		child_signals();		execv(cmdpath,cmdargv);		perror(cmdpath);		_exit(255);				/* end of spawned process */	}	/* end of if child process */	wait_status = 0;	while(((itmp = wait(&wait_status)) != execpid) && (itmp != -1))		;	last_child_wait_status = wait_status;	last_child_wait_pid = execpid;/* resume our normally scheduled program */	lreset_ksr();				/* restore comm line params */	ttymode(old_ttymode);		/* control tty back to original */	if(restart_rcvr)		start_rcvr_process(1);	xmtr_signals();	return(last_child_wait_status);}	/* end of exec_cmd *//*+-------------------------------------------------------------------------	expand_wildcard_list(wild,&expcmd)called with 'foo <wildcardlist>' for command expansion prior to exec()         or '<wildcardlist>' to expand a list of files.If called with 'foo'-style wild, anything you want to protect from csh globbing or other interpretation must be properly protected (quoted) --AND quoting will be removed one level by the csh.if return 0, wild has been expanded, expcmd must be free()'d when doneif return -1, error, expcmd has error message (static message: DO NOT FREE)--------------------------------------------------------------------------*/expand_wildcard_list(wild,expcmd)char *wild;char **expcmd;{	register char *cptr;#define P_READ 0#define P_WRITE 1	PID_T pipe_pid;	int stdout_pipe[2];	int stderr_pipe[2];	int count;	int expcmd_size = 0;	int itmp;	int wait_status;	int restart_rcvr = need_rcvr_restart();	FILE *fp_pipe = (FILE *)0;	char *echo_cmd;	static char s132[132];	char *strchr();	static char *pipe_err_msg = "system error: no pipe";	static char *mem_err_msg = "system error: no memory";	if(strchr(wild,'<') || strchr(wild,'>') || strchr(wild,'&'))	{		*expcmd = "illegal characters: '<', '>' or '&'";		return(-1);	}	if(pipe(stdout_pipe) < 0)	{		*expcmd = pipe_err_msg;		return(-1);	}	if(pipe(stderr_pipe) < 0)	{		close(stdout_pipe[P_READ]);		close(stdout_pipe[P_WRITE]);		*expcmd = pipe_err_msg;		return(-1);	}	if(!(echo_cmd = malloc(strlen(wild) + 10)))	{		close(stdout_pipe[P_READ]);		close(stdout_pipe[P_WRITE]);		close(stderr_pipe[P_READ]);		close(stderr_pipe[P_WRITE]);		*expcmd = mem_err_msg;		return(-1);	}	strcpy(echo_cmd,"echo ");	strcat(echo_cmd,wild);	kill_rcvr_process(SIGUSR1);		/* stop receiver process gracefully */	signal(SIGINT,SIG_IGN);	signal(SIGQUIT,SIG_IGN);	signal(SIGUSR1,SIG_IGN);	signal(SIGUSR2,SIG_IGN);	signal(SIGCLD,SIG_DFL);	if((pipe_pid = smart_fork()) == 0)	{	int null = open("/dev/null",O_WRONLY,0);		close(stdout_pipe[P_READ]);		close(TTYOUT);		dup(stdout_pipe[P_WRITE]);		close(stdout_pipe[P_WRITE]);		close(TTYERR);		dup(stderr_pipe[P_WRITE]);		close(stderr_pipe[P_WRITE]);		close(null);		child_signals();#ifdef linux		/* Most Linux systems don't have a csh */		execl("/bin/sh","sh","-c",echo_cmd,(char *)0);#else		execl("/bin/csh","csh","-e","-f","-c",echo_cmd,(char *)0);#endif		_exit(255);	}#if defined(FORK_DEBUG)	sprintf(s132,"DEBUG expand pid %d",pipe_pid);	ecu_log_event(getpid(),s132);		/* expand_wildcard_list */#endif	free(echo_cmd);	close(stdout_pipe[P_WRITE]);	close(stderr_pipe[P_WRITE]);	if(pipe_pid == -1)	{		close(stdout_pipe[P_READ]);		close(stderr_pipe[P_READ]);		*expcmd = "could not fork";		if(restart_rcvr)			start_rcvr_process(0);		xmtr_signals();		return(-1);	}	if(!(*expcmd = malloc(expcmd_size = ESD_MAXSIZE)))	{		close(stdout_pipe[P_READ]);		close(stderr_pipe[P_READ]);		kill(pipe_pid,SIGKILL);		*expcmd = mem_err_msg;		if(restart_rcvr)			start_rcvr_process(0);		xmtr_signals();		return(-1);	}	if(!(fp_pipe = fdopen(stdout_pipe[P_READ],"r")) ||		((count = fread(*expcmd,1,expcmd_size,fp_pipe)) < 0))	{			free(*expcmd);			kill(pipe_pid,SIGKILL);			close(stdout_pipe[P_READ]);			close(stderr_pipe[P_READ]);			*expcmd = "error reading wild list expansion";			if(restart_rcvr)				start_rcvr_process(0);			xmtr_signals();			return(-1);	}	/*	 * make sure stdout is closed	 */	if(fp_pipe)		fclose(fp_pipe);	close(stdout_pipe[P_READ]);	/*	 * place trailing null	 * kill trailing new line	 */	if(count)	{		cptr = (*expcmd) + count;		*cptr-- = 0;		if(*cptr == '\n')		{			*cptr = 0;			count--;		}	}	/*	 * if no expansion, read stderr to find out why	 */	if(!count)	{		free(*expcmd);		count = read(stderr_pipe[P_READ],s132,sizeof(s132) - 1);		if(count < 0)			strcpy(s132,errno_text(errno));		else			s132[count] = 0;		if(s132[count - 1] == '\n')			s132[count - 1] = 0;		close(stderr_pipe[P_READ]);		if(strncmp(s132,"echo: ",6))			*expcmd = s132;		else			*expcmd = s132 + 6;		if(restart_rcvr)			start_rcvr_process(0);		return(-1);	}	/*	 * clean up zombie	 */	wait_status = 0;	while(((itmp = wait(&wait_status)) != pipe_pid) && (itmp != -1))		;	xmtr_signals();	/*	 * if bad termination status, read stderr	 */	if(wait_status)	{		free(*expcmd);		count = read(stderr_pipe[P_READ],s132,sizeof(s132) - 1);		if(count < 0)			strcpy(s132,errno_text(errno));		else			s132[count] = 0;		if(s132[count - 1] == '\n')			s132[count - 1] = 0;		close(stderr_pipe[P_READ]);		if(strncmp(s132,"echo: ",6))			*expcmd = s132;		else			*expcmd = s132 + 6;		if(restart_rcvr)			start_rcvr_process(0);		return(-1);	}	close(stderr_pipe[P_READ]);	/*	 * whew: we have (I think) a file list expansion	 */	if(restart_rcvr)		start_rcvr_process(0);	return(0);}	/* end of expand_wildcard_list *//* vi: set tabstop=4 shiftwidth=4: *//* end of ecufork.c */

⌨️ 快捷键说明

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