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

📄 eculine.c

📁 一个通讯程序源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	lopen()returns negative LINST_ codes if failure else positive pid using lineelse 0 if successful open------------------------------------------------------------------------*/intlopen(){	int itmp;	struct stat ttystat;#ifdef SHARE_DEBUG	char s80[80];	sprintf(s80,"lopen Liofd=%d Lline=%s line_lock_status=%d",	    shm->Liofd,shm->Lline,	    line_lock_status(shm->Lline));	ecu_log_event((int)xmtr_pid,s80);#endif	/*	 * system independent checks	 */	if(shm->Liofd >= 0)		return(LINST_ALREADY);	if(!strcmp(shm->Lline,"/dev/tty"))		return(LINST_INVALID);	if(stat(shm->Lline,&ttystat) < 0)	{		if(errno == ENOENT)			return(LINST_NODEV);		return(LINST_OPNFAIL);	}	if((ttystat.st_mode & S_IFMT) != S_IFCHR)		return(LINST_NOTCHR);	if(ulindex(shm->Lline,"pty") > -1)		return(LINST_NOPTY);	/*	 * lock the tty 	 */	if((itmp = lock_tty(shm->Lline)) && (itmp != LINST_WEGOTIT))		return(itmp);	/*	 * if appropriate, make sure we have ungetty'd the line	 */#if defined(USE_ECUUNGETTY)	ungetty_return_all_but(shm->Lline);	if(!in_ungetty_list(shm->Lline))	{		if(itmp = ungetty_get_line(shm->Lline))		{			sprintf(lopen_err_str,"ecuungetty error - %s",linst_err_text(itmp));			unlock_tty(shm->Lline);			return(itmp);		}	}#endif	/*	 * rarely an open will hang despite our wisdom and prayer	 */	if(setjmp(_insurance_jmpbuf))	{		alarm(0);		signal(SIGALRM,SIG_IGN);		errno = EIO;		sprintf(lopen_err_str,"open error - %s",errno_text(errno));		unlock_tty(shm->Lline);		return(LINST_OPNFAIL);	}	/*	 * open the tty using non-blocking I/O to bypass DCD wait	 * handle EAGAIN for SVR4 per kortcs!tim	 */	for (itmp=0; ; ++itmp)	{		signal(SIGALRM,lopen_failed);#ifdef sun		alarm(10);#else		alarm(5);#endif		shm->Liofd = open(shm->Lline,O_RDWR | O_NDELAY,0666);		alarm(0);		signal(SIGALRM,SIG_IGN);		if(shm->Liofd >= 0)			break;		if((itmp < 5) && (errno == EAGAIN))		{			(void)signal(SIGALRM,SIG_DFL);			alarm(0);			sleep(2);			continue;		}		if (errno == EACCES)		{			struct passwd *pw = getpwuid(ttystat.st_uid);			endpwent();			if(pw)			{				sprintf(lopen_err_str,					"cannot open line owned by %s (mode=%3o)",					pw->pw_name,ttystat.st_mode & 0777);			}			else			{				sprintf(lopen_err_str,					"open error - try chmod +rw %s",shm->Lline);			}		}		else 			sprintf(lopen_err_str,"open error - %s",errno_text(errno));		unlock_tty(shm->Lline);		return(LINST_OPNFAIL);	}	/*	 * turn off non-blocking I/O and set initial termio, including CLOCAL	 */	fcntl(shm->Liofd,F_GETFL,&itmp);	itmp &= ~O_NDELAY;	fcntl(shm->Liofd,F_SETFL,itmp);	ioctl(shm->Liofd,TCGETA,(char *) Ltermio);	Ltermio->c_iflag = (IGNPAR | IGNBRK | shm->Lxonxoff);	Ltermio->c_oflag = 0;	Ltermio->c_cflag |= (CLOCAL | CREAD | HUPCL);	Ltermio->c_lflag = 0;	Ltermio->c_cc[VMIN]   = 1;	Ltermio->c_cc[VTIME]  = 1;	lset_baud_rate(0);		/* do not perform ioctl */	lset_parity(1);			/* do perform ioctl */#if defined(SVR4)	hx_flag = 0;			/* hardware flow control "memory" */#endif	lopen_err_str[0] = 0;	/* no error this time! */	return(0);}	/* end of lopen *//*+-------------------------------------------------------------------------	lclose_failed(sig) - see lclose() below--------------------------------------------------------------------------*/voidlclose_failed(sig)int sig;{	if(sig != SIGALRM)		ff(se,"error %d in lclose_failed: tell wht@n4hgf\r\n",sig);	longjmp(_insurance_jmpbuf,1);}	/* end of lclose_failed *//*+-----------------------------------------------------------------------	lclose() - close the lineThe FAS driver and others hang on a close until all output for a linehas drained.  Sometimes during a hangup, a noisy XOFF can be received.Other changeces for failure include a DCE which drops CTS and leavesit off, locking the line up if there is output waiting to go out.To make sure the line is actually closed in these situations, a SIGLARMhandler is used.------------------------------------------------------------------------*/voidlclose(){	struct termio ttio;	int attempt2 = 0;#ifdef SHARE_DEBUG	char s80[80];	sprintf(s80,"lclose Liofd=%d Lline=%s line_lock_status=%d",		shm->Liofd,shm->Lline,		line_lock_status(shm->Lline));	ecu_log_event((int)xmtr_pid,s80);#endif	if(shm->Liofd < 0)		return;ATTEMPT: /* endless loop because we cannot get out anyway unless success */	signal(SIGALRM,lclose_failed);#ifdef sun	alarm(10);#else	alarm(5);#endif	if(setjmp(_insurance_jmpbuf))	{	/* close failed */		signal(SIGALRM,SIG_IGN);		alarm(0);		ff(se,"\r\nclose failed (remote XOFF?) ... retrying close\r\n");		lclear_xmtr_xoff();		ttio = *Ltermio;		ttio.c_iflag &= ~(IXON | IXOFF);		ttio.c_cflag &= (CSIZE | CSTOPB | CREAD | PARENB | PARODD);		ioctl(shm->Liofd,TCSETA,(char *)&ttio);		lflush(2);		attempt2 = 1;		goto ATTEMPT;	}	if(!attempt2)	{		lclear_xmtr_xoff();		ldraino(1);	}	lCLOCAL(1);	close(shm->Liofd);	signal(SIGALRM,SIG_IGN);	alarm(0);	unlock_tty(shm->Lline);	shm->Lmodem_already_init = 0;	shm->Lconnected = 0;	shm->Liofd = -1;}	/* end of lclose *//*+-------------------------------------------------------------------------	lflash_dtr() - flash DTRDTR is lowered for 300 msec and raised again.  After raising,we pause a while for a possibly slow DCE to rereap it's fecal materialexpects:  Ltermio - current termio status of line          shm->Liofd - current line fd          shm->Lline - /dev/ttyxx name of lineOn SunOS and SVR4, an open/close of the line is required to get DTR backup. SVR3 does not seem to need this (ISC asy, SCO sio, Uwe Doering's FAS)but we do it anyway--------------------------------------------------------------------------*/voidlflash_dtr(){#undef NEED_REOPEN#if defined(sun) || defined(SVR4)#define NEED_REOPEN	int tempfd;#endif	struct termio b0t;	/*	 * copy termio but CBAUD to B0	 */	b0t = *Ltermio;	b0t.c_cflag &= ~CBAUD;	/* B0 */	/*	 * drop DTR for a while	 */	ioctl(shm->Liofd,TCSETA,(char *)&b0t);		/* drop DTR */	/*	 * DTR will not come back on some systems without open/close line	 */#ifdef NEED_REOPEN	if ((tempfd = open(shm->Lline, O_NDELAY | O_RDWR, 0666)) != -1)		close(tempfd);	else	{		int save_errno = errno;		char s128[128];		sprintf(s128,"FLASH DTR line reopen failed (%.80s)",			errno_text(errno));		ecu_log_event(shm->xmtr_pid,s128);		pputs(s128);		pputs("\n");		errno = save_errno;		termecu(TERMECU_LINE_OPEN_ERROR);	}#else	/*	 * ensure DTR low for 300 msec	 * (the tempfd open/close takes plenty long enough)	 */	Nap(300L);#endif	/*	 * reestablish baud rate 	 * (raise DTR if the open/close line did not do it)	 */	ioctl(shm->Liofd,TCSETA,(char *)Ltermio);	/* raise DTR */	Nap(300L);	/* nap to give a lazy DCE some time */#undef NEED_REOPEN}	/* end of lflash_dtr *//*+-------------------------------------------------------------------------	lxon_xoff(flag)IXON specifies whether or not we respond to xon/xoff charactersIXOFF specifies whether or not we generate XON/XOFF characters--------------------------------------------------------------------------*/voidlxon_xoff(flag)int flag;{	if(flag & IXON)		Ltermio->c_iflag |= IXON;	else		Ltermio->c_iflag &= ~IXON;	if(flag & IXOFF)		Ltermio->c_iflag |= IXOFF;	else		Ltermio->c_iflag &= ~IXOFF;	shm->Lxonxoff = Ltermio->c_iflag & (IXON|IXOFF);	ioctl(shm->Liofd,TCSETA,(char *)Ltermio);#if 0	Nap(400L);#endif}	/* end of lflash_dtr *//*+-------------------------------------------------------------------------	lget_xon_xoff(ixon,ixoff)--------------------------------------------------------------------------*/voidlget_xon_xoff(ixon,ixoff)int *ixon;int *ixoff;{	*ixon  = Ltermio->c_iflag & IXON;	*ixoff = Ltermio->c_iflag & IXOFF;}	/* end of lget_xon_xoff *//*+-------------------------------------------------------------------------	set_xon_xoff_by_arg(arg)--------------------------------------------------------------------------*/intset_xon_xoff_by_arg(arg)char *arg;{	if(ulcmpb(arg,"on") < 0)		shm->Lxonxoff = IXON | IXOFF;	else if(ulcmpb(arg,"off") < 0)		shm->Lxonxoff = 0;	else if(ulcmpb(arg,"out") < 0)		shm->Lxonxoff = IXON;	else if(ulcmpb(arg,"in") < 0)		shm->Lxonxoff = IXOFF;	else		return(-1);	Ltermio->c_iflag &= ~(IXON|IXOFF);	Ltermio->c_iflag |= shm->Lxonxoff;	ioctl(shm->Liofd,TCSETA,(char *)Ltermio);	return(0);}	/* end of set_xon_xoff_by_arg *//*+-------------------------------------------------------------------------	xon_status()--------------------------------------------------------------------------*/char *xon_status(){	switch(shm->Lxonxoff)	{		case 0            : return("off");		case IXON         : return("in off, out on");		case        IXOFF : return("in on, out off");		case IXON | IXOFF : return("on");	}	return("logic error");}	/* end of xon_status *//*+-------------------------------------------------------------------------	lCLOCAL(flag) - set line CLOCAL stateflag == 0: turn off CLOCAL to catch DCD loss     == 1: turn on CLOCAL to ignore modem signalsdoes not let CLOCAL be turned off if not Lconnectedalso resets global zero_length_read_detected--------------------------------------------------------------------------*/voidlCLOCAL(flag)int flag;{	if(flag)		Ltermio->c_cflag |= CLOCAL;	else if(shm->Lconnected)		Ltermio->c_cflag &= ~CLOCAL;	else		Ltermio->c_cflag |= CLOCAL;	zero_length_read_detected = 0;	lreset_ksr();	/* do the ioctl */#ifdef DEBUG_CLOCAL	{		char s128[128];		sprintf(s128,"lCLOCAL(%d) connected=%c CLOCAL set %o",			flag,shm->Lconnected?'y':'n',Ltermio->c_cflag & CLOCAL?1:0);		ecu_log_event((int)xmtr_pid,s128);		pprintf("%s\n",s128);	}#endif}	/* end of lCLOCAL *//*+-------------------------------------------------------------------------	ldcdwatch(flag) - set DCD watcher state--------------------------------------------------------------------------*/voidldcdwatch(flag)int flag;{	shm->Ldcdwatch = flag;	dcdwatch_set = 1;	lCLOCAL(!flag);}	/* end of ldcdwatch *//*+-------------------------------------------------------------------------	ldcdwatch_str(flagstr) - string version of ldcdwatchreturn 0 if successful or -1 if bad flagstr--------------------------------------------------------------------------*/intldcdwatch_str(flagstr)char *flagstr;{	static STR_CLASSIFY sc[] = {		{ "1",			1,DCDW_ON },		{ "yes",		1,DCDW_ON },		{ "on",			2,DCDW_ON },		{ "0",			1,DCDW_ON },		{ "no",			1,DCDW_OFF },		{ "off",		3,DCDW_OFF },		{ "terminate",	1,DCDW_TERMINATE },		{ (char *)0,	0,-1 }	};	int token;	if((token = str_classify(sc,flagstr)) < 0)		return(-1);	ldcdwatch(token);	return(0);		}	/* end of ldcdwatch_str *//*+-------------------------------------------------------------------------	lzero_length_read_detected() - read from line returned zero lengthThis must mean CLOCAL was off and DCD is/went low.  We do different thingsdepending in the xmtr and rcvr processIf we return, the condition has ben handled and reads may be retriedsafely or other appropriate operations performed; otherwise ECU isterminated.--------------------------------------------------------------------------*/voidlzero_length_read_detected(){	zero_length_read_detected = 1;	if(getpid() == xmtr_pid)	/* if we are in the transmitter */	{#ifdef DEBUG_CLOCAL		ecu_log_event((int)xmtr_pid,"lzero xmtr");		pprintf("lzero xmtr\n");#endif		if(shm->Lconnected)		{			extern ulong colors_current;			ulong colors_at_entry = colors_current;			fputs("\r\n",se);			setcolor(colors_notify);			fputs("[connection terminated]",se);			setcolor(colors_at_entry);			fputs("\r\n",se);			DCE_now_on_hook();	/* does a lCLOCAL(1); */		}		else			lCLOCAL(1);		Nap(1000L);		lflush(2);		if(shm->Ldcdwatch == DCDW_TERMINATE)			termecu(0);		shmx_unpause_rcvr();	}	else	/* we are in the receiver */	{#ifdef DEBUG_CLOCAL		ecu_log_event((int)xmtr_pid,"lzero rcvr");		pprintf("lzero rcvr\n");#endif		/*		 * make line "safe" to read from immediately;		 * however, if CLOCAL was set and we get a zero length read,		 * we are in some kind of unknown trouble		 */		if(Ltermio->c_cflag & CLOCAL)	/* zero len read with CLOCAL? */		{								/* then die ECU */			errno = EIO;			termecu(TERMECU_LINE_READ_ERROR);		}		lCLOCAL(1);		shmr_notify_xmtr_of_DCD_loss();		pause();		/* wait for unpause */	}}	/* end of lzero_length_read_detected *//* vi: set tabstop=4 shiftwidth=4: *//* end of eculine.c */

⌨️ 快捷键说明

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