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

📄 pty.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
字号:
/* * /dev/ptyXX  (A first version for pseudo-terminals) * *  Author: Fernando RUIZ CASAS (fernando.ruiz@ctv.es) *  May 2001 * *  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. *  *  $Id: pty.c,v 1.3 2002/05/28 16:20:54 joel Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif/*-----------------------------------------*/#include <termios.h>#include <rtems.h>#include <rtems/libio.h>#include <rtems/pty.h>#include <rtems/bspIo.h>/*-----------------------------------------*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>/*-----------------------------------------*/#define IAC_ESC    255#define IAC_DONT   254#define IAC_DO     253#define IAC_WONT   252#define IAC_WILL   251#define IAC_SB     250#define IAC_GA     249#define IAC_EL     248#define IAC_EC     247#define IAC_AYT    246#define IAC_AO     245#define IAC_IP     244#define IAC_BRK    243#define IAC_DMARK  242#define IAC_NOP    241#define IAC_SE     240#define IAC_EOR    239struct pty_tt;typedef struct pty_tt pty_t;struct pty_tt { char                     *devname; struct rtems_termios_tty *ttyp; tcflag_t                  c_cflag; int                       opened; int                       socket; int                       last_cr; int                       iac_mode;   };int ptys_initted=FALSE;pty_t ptys[MAX_PTYS];/* This procedure returns the devname for a pty slot free. * If not slot availiable (field socket>=0)  *  then the socket argument is closed */char *  get_pty(int socket) {	int ndx;	if (!ptys_initted) return NULL;	for (ndx=0;ndx<MAX_PTYS;ndx++) {		if (ptys[ndx].socket<0) {			ptys[ndx].socket=socket;			return ptys[ndx].devname;		};	};	close(socket);	return NULL;}/*-----------------------------------------------------------*//* * The NVT terminal is negociated in PollRead and PollWrite * with every BYTE sendded or received.  * A litle status machine in the pty_read_byte(int minor)  *  */const char IAC_AYT_RSP[]="\r\nAYT? Yes, RTEMS-SHELL is here\r\n";const char IAC_BRK_RSP[]="<*Break*>";const char IAC_IP_RSP []="<*Interrupt*>";staticint send_iac(int minor,unsigned char mode,unsigned char option) {	unsigned char buf[3];	buf[0]=IAC_ESC;	buf[1]=mode;	buf[2]=option;	return write(ptys[minor].socket,buf,sizeof(buf));}int read_pty(int minor) { /* Characters writed in the client side*/	 unsigned char value;	 int count;	 int result;	 count=read(ptys[minor].socket,&value,sizeof(value));	 if (count<1) {          fclose(stdin);		           fclose(stdout);		           fclose(stderr);		 	  /* If you don't read from the socket the system ends the task */	  rtems_task_delete(RTEMS_SELF);	 };	 switch(ptys[minor].iac_mode) {          case IAC_ESC:	       ptys[minor].iac_mode=0;               switch(value) {                case IAC_ESC :		     return IAC_ESC;                case IAC_DONT:                case IAC_DO  :                case IAC_WONT:                case IAC_WILL:		     ptys[minor].iac_mode=value;		     return -1;                case IAC_SB  :		     return -100;                case IAC_GA  :		     return -1;                case IAC_EL  :		     return 0x03; /* Ctrl-C*/                case IAC_EC  :		     return '\b';		case IAC_AYT :	             write(ptys[minor].socket,IAC_AYT_RSP,strlen(IAC_AYT_RSP));		     return -1;                case IAC_AO  :		     return -1;                case IAC_IP  :	             write(ptys[minor].socket,IAC_IP_RSP,strlen(IAC_IP_RSP));		     return -1;		case IAC_BRK :	             write(ptys[minor].socket,IAC_BRK_RSP,strlen(IAC_BRK_RSP));		     return -1;                case IAC_DMARK:		     return -2;                case IAC_NOP :		     return -1;                case IAC_SE  :		     return -101;                case IAC_EOR :		     return -102;		default      :		     return -1;	       };	       break;	  case IAC_WILL:	       ptys[minor].iac_mode=0;	       if (value==34){send_iac(minor,IAC_DONT,   34);       /*LINEMODE*/ 	                      send_iac(minor,IAC_DO  ,    1);} else /*ECHO    */	                     {send_iac(minor,IAC_DONT,value);};	       return -1;	  case IAC_DONT:	       ptys[minor].iac_mode=0;	       return -1;	  case IAC_DO  :	       ptys[minor].iac_mode=0;	       if (value==3) {send_iac(minor,IAC_WILL,    3);} else /* GO AHEAD*/	       if (value==1) {                               } else /* ECHO */	                     {send_iac(minor,IAC_WONT,value);};	       return -1;	  case IAC_WONT:	       ptys[minor].iac_mode=0;	       if (value==1) {send_iac(minor,IAC_WILL,    1);} else /* ECHO */	                     {send_iac(minor,IAC_WONT,value);};	       return -1;	  default:	       ptys[minor].iac_mode=0;	       if (value==IAC_ESC) {                     ptys[minor].iac_mode=value;		     return -1;	       } else {		     result=value;  		     if ((value=='\n') && (ptys[minor].last_cr)) result=-1;		     ptys[minor].last_cr=(value=='\r');		     return result;	       };	 };	}/*-----------------------------------------------------------*/static int ptySetAttributes(int minor,const struct termios *t);static int ptyPollInitialize(int major,int minor,void * arg) ;static int ptyShutdown(int major,int minor,void * arg) ;static int ptyPollWrite(int minor, const char * buf,int len) ;static int ptyPollRead(int minor) ;const rtems_termios_callbacks * pty_get_termios_handlers(int polled) ;/*-----------------------------------------------------------*//* Set the 'Hardware'                                        */ /*-----------------------------------------------------------*/static intptySetAttributes(int minor,const struct termios *t) {	if (minor<MAX_PTYS) {		 ptys[minor].c_cflag=t->c_cflag;		} else {	 return -1;	};	return 0;}/*-----------------------------------------------------------*/static int ptyPollInitialize(int major,int minor,void * arg) {	rtems_libio_open_close_args_t * args = arg;	struct termios t;        if (minor<MAX_PTYS) {	         if (ptys[minor].socket<0) return -1;			 ptys[minor].opened=TRUE;	 ptys[minor].ttyp=args->iop->data1;	 t.c_cflag=B9600|CS8;/* termios default */	 return ptySetAttributes(minor,&t);	} else {	 return -1;	};}/*-----------------------------------------------------------*/static int ptyShutdown(int major,int minor,void * arg) {        if (minor<MAX_PTYS) {		 ptys[minor].opened=FALSE;         if (ptys[minor].socket>=0) close(ptys[minor].socket);	 ptys[minor].socket=-1;	 chown(ptys[minor].devname,2,0);	} else {	 return -1;	};	return 0;}/*-----------------------------------------------------------*//* Write Characters into pty device                          */ /*-----------------------------------------------------------*/static intptyPollWrite(int minor, const char * buf,int len) {	int count;        if (minor<MAX_PTYS) {	         if (ptys[minor].socket<0) return -1;			 count=write(ptys[minor].socket,buf,len);	} else {	 count=-1;	};	return count;}/*-----------------------------------------------------------*/static intptyPollRead(int minor) {	int result;        if (minor<MAX_PTYS) {	         if (ptys[minor].socket<0) return -1;			 result=read_pty(minor);	 return result;	};	return -1;}/*-----------------------------------------------------------*/static const rtems_termios_callbacks pty_poll_callbacks = {	ptyPollInitialize,	/* FirstOpen*/	ptyShutdown,		/* LastClose*/	ptyPollRead,		/* PollRead  */	ptyPollWrite,		/* Write */	ptySetAttributes,	/* setAttributes */	NULL,			/* stopRemoteTX */	NULL,			/* StartRemoteTX */	0 			/* outputUsesInterrupts */};/*-----------------------------------------------------------*/const rtems_termios_callbacks * pty_get_termios_handlers(int polled) {	return &pty_poll_callbacks;}/*-----------------------------------------------------------*/void init_ptys(void) {	int ndx;	for (ndx=0;ndx<MAX_PTYS;ndx++) {		ptys[ndx].devname=malloc(strlen("/dev/ptyXX")+1);		sprintf(ptys[ndx].devname,"/dev/pty%X",ndx);		ptys[ndx].ttyp=NULL;		ptys[ndx].c_cflag=CS8|B9600;		ptys[ndx].socket=-1;		ptys[ndx].opened=FALSE;	};	ptys_initted=TRUE;}/*-----------------------------------------------------------*//*  pty_initialize * *  This routine initializes the pty IO driver. * *  Input parameters: NONE * *  Output parameters:  NONE * *  Return values: *//*-----------------------------------------------------------*/rtems_device_driver pty_initialize(  rtems_device_major_number  major,  rtems_device_minor_number  minor,  void                      *arg){  int ndx;	  rtems_status_code status ;  /*    * Set up ptys   */  init_ptys();  /*   * Register the devices   */  for (ndx=0;ndx<MAX_PTYS;ndx++) {   status = rtems_io_register_name(ptys[ndx].devname, major, ndx);   if (status != RTEMS_SUCCESSFUL)     rtems_fatal_error_occurred(status);   chmod(ptys[ndx].devname,0660);   chown(ptys[ndx].devname,2,0); /* tty,root*/  };  printk("Device: /dev/pty%X../dev/pty%X (%d)pseudo-terminals registered.\n",0,MAX_PTYS-1,MAX_PTYS);  return RTEMS_SUCCESSFUL;}/* *  Open entry point */rtems_device_driver pty_open(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  rtems_status_code sc ;  sc = rtems_termios_open(major,minor,arg,pty_get_termios_handlers(FALSE));  return sc;} /* *  Close entry point */rtems_device_driver pty_close(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  return rtems_termios_close(arg);}/* * read bytes from the pty */rtems_device_driver pty_read(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  return rtems_termios_read(arg);}/* * write bytes to the pty */rtems_device_driver pty_write(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  return rtems_termios_write(arg);}/* *  IO Control entry point */rtems_device_driver pty_control(  rtems_device_major_number major,  rtems_device_minor_number minor,  void                    * arg){  return rtems_termios_ioctl(arg);}

⌨️ 快捷键说明

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