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

📄 fhandler_serial.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 2 页
字号:
	if (!ClearCommError (get_handle (), &ev, &st) || !st.cbInQue)	  break;      }  return 0;}/* tcsetattr: POSIX 7.2.1.1 */intfhandler_serial::tcsetattr (int action, const struct termios *t){  /* Possible actions:    TCSANOW:   immediately change attributes.    TCSADRAIN: flush output, then change attributes.    TCSAFLUSH: flush output and discard input, then change attributes.  */  BOOL dropDTR = FALSE;  COMMTIMEOUTS to;  DCB ostate, state;  unsigned int ovtime = vtime_, ovmin = vmin_;  int tmpDtr, tmpRts;  tmpDtr = tmpRts = 0;  termios_printf ("action %d", action);  if ((action == TCSADRAIN) || (action == TCSAFLUSH))    {      FlushFileBuffers (get_handle ());      termios_printf ("flushed file buffers");    }  if (action == TCSAFLUSH)    PurgeComm (get_handle (), (PURGE_RXABORT | PURGE_RXCLEAR));  /* get default/last comm state */  if (!GetCommState (get_handle (), &ostate))    return -1;  state = ostate;  /* -------------- Set baud rate ------------------ */  /* FIXME: WIN32 also has 14400, 56000, 128000, and 256000.     Unix also has 230400. */  switch (t->c_ospeed)    {      case B0:	/* drop DTR */	dropDTR = TRUE;	state.BaudRate = 0;	break;      case B110:	state.BaudRate = CBR_110;	break;      case B300:	state.BaudRate = CBR_300;	break;      case B600:	state.BaudRate = CBR_600;	break;      case B1200:	state.BaudRate = CBR_1200;	break;      case B2400:	state.BaudRate = CBR_2400;	break;      case B4800:	state.BaudRate = CBR_4800;	break;      case B9600:	state.BaudRate = CBR_9600;	break;      case B19200:	state.BaudRate = CBR_19200;	break;      case B38400:	state.BaudRate = CBR_38400;	break;      case B57600:	state.BaudRate = CBR_57600;	break;      case B115200:	state.BaudRate = CBR_115200;	break;      default:	/* Unsupported baud rate! */	termios_printf ("Invalid t->c_ospeed %d", t->c_ospeed);	set_errno (EINVAL);	return -1;    }  /* -------------- Set byte size ------------------ */  switch (t->c_cflag & CSIZE)    {      case CS5:	state.ByteSize = 5;	break;      case CS6:	state.ByteSize = 6;	break;      case CS7:	state.ByteSize = 7;	break;      case CS8:	state.ByteSize = 8;	break;      default:	/* Unsupported byte size! */	termios_printf ("Invalid t->c_cflag byte size %d",			t->c_cflag & CSIZE);	set_errno (EINVAL);	return -1;    }  /* -------------- Set stop bits ------------------ */  if (t->c_cflag & CSTOPB)    state.StopBits = TWOSTOPBITS;  else    state.StopBits = ONESTOPBIT;  /* -------------- Set parity ------------------ */  if (t->c_cflag & PARENB)    state.Parity = (t->c_cflag & PARODD) ? ODDPARITY : EVENPARITY;  else    state.Parity = NOPARITY;  state.fBinary = TRUE;     /* Binary transfer */  state.EofChar = 0;	    /* No end-of-data in binary mode */  state.fNull = FALSE;      /* Don't discard nulls in binary mode */  /* -------------- Parity errors ------------------ */  /* fParity combines the function of INPCK and NOT IGNPAR */  if ((t->c_iflag & INPCK) && !(t->c_iflag & IGNPAR))    state.fParity = TRUE;   /* detect parity errors */  else    state.fParity = FALSE;  /* ignore parity errors */  /* Only present in Win32, Unix has no equivalent */  state.fErrorChar = FALSE;  state.ErrorChar = 0;  /* -------------- Set software flow control ------------------ */  /* Set fTXContinueOnXoff to FALSE.  This prevents the triggering of a     premature XON when the remote device interprets a received character     as XON (same as IXANY on the remote side).  Otherwise, a TRUE     value separates the TX and RX functions. */  state.fTXContinueOnXoff = TRUE;     /* separate TX and RX flow control */  /* Transmission flow control */  if (t->c_iflag & IXON)    state.fOutX = TRUE;   /* enable */  else    state.fOutX = FALSE;  /* disable */  /* Reception flow control */  if (t->c_iflag & IXOFF)    state.fInX = TRUE;    /* enable */  else    state.fInX = FALSE;   /* disable */  /* XoffLim and XonLim are left at default values */  state.XonChar = (t->c_cc[VSTART] ? t->c_cc[VSTART] : 0x11);  state.XoffChar = (t->c_cc[VSTOP] ? t->c_cc[VSTOP] : 0x13);  /* -------------- Set hardware flow control ------------------ */  /* Disable DSR flow control */  state.fOutxDsrFlow = FALSE;  /* Some old flavors of Unix automatically enabled hardware flow     control when software flow control was not enabled.  Since newer     Unices tend to require explicit setting of hardware flow-control,     this is what we do. */  /* RTS/CTS flow control */  if (t->c_cflag & CRTSCTS)    {							/* enable */      state.fOutxCtsFlow = TRUE;      state.fRtsControl = RTS_CONTROL_HANDSHAKE;    }  else    {							/* disable */      state.fRtsControl = RTS_CONTROL_ENABLE;      state.fOutxCtsFlow = FALSE;      tmpRts = TIOCM_RTS;    }  if (t->c_cflag & CRTSXOFF)    state.fRtsControl = RTS_CONTROL_HANDSHAKE;  /* -------------- DTR ------------------ */  /* Assert DTR on device open */  state.fDtrControl = DTR_CONTROL_ENABLE;  /* -------------- DSR ------------------ */  /* Assert DSR at the device? */  if (t->c_cflag & CLOCAL)    state.fDsrSensitivity = FALSE;  /* no */  else    state.fDsrSensitivity = TRUE;   /* yes */  /* -------------- Error handling ------------------ */  /* Since read/write operations terminate upon error, we     will use ClearCommError() to resume. */  state.fAbortOnError = TRUE;  /* -------------- Set state and exit ------------------ */  if (memcmp (&ostate, &state, sizeof (state)) != 0)    SetCommState (get_handle (), &state);  set_r_binary ((t->c_iflag & IGNCR) ? 0 : 1);  set_w_binary ((t->c_oflag & ONLCR) ? 0 : 1);  if (dropDTR == TRUE)    {      EscapeCommFunction (get_handle (), CLRDTR);      tmpDtr = 0;    }  else    {      /* FIXME: Sometimes when CLRDTR is set, setting      state.fDtrControl = DTR_CONTROL_ENABLE will fail.  This      is a problem since a program might want to change some      parameters while DTR is still down. */      EscapeCommFunction (get_handle (), SETDTR);      tmpDtr = TIOCM_DTR;    }  rts = tmpRts;  dtr = tmpDtr;  /*  The following documentation on was taken from "Linux Serial Programming  HOWTO".  It explains how MIN (t->c_cc[VMIN] || vmin_) and TIME  (t->c_cc[VTIME] || vtime_) is to be used.  In non-canonical input processing mode, input is not assembled into  lines and input processing (erase, kill, delete, etc.) does not  occur. Two parameters control the behavior of this mode: c_cc[VTIME]  sets the character timer, and c_cc[VMIN] sets the minimum number of  characters to receive before satisfying the read.  If MIN > 0 and TIME = 0, MIN sets the number of characters to receive  before the read is satisfied. As TIME is zero, the timer is not used.  If MIN = 0 and TIME > 0, TIME serves as a timeout value. The read will  be satisfied if a single character is read, or TIME is exceeded (t =  TIME *0.1 s). If TIME is exceeded, no character will be returned.  If MIN > 0 and TIME > 0, TIME serves as an inter-character timer. The  read will be satisfied if MIN characters are received, or the time  between two characters exceeds TIME. The timer is restarted every time  a character is received and only becomes active after the first  character has been received.  If MIN = 0 and TIME = 0, read will be satisfied immediately. The  number of characters currently available, or the number of characters  requested will be returned. According to Antonino (see contributions),  you could issue a fcntl(fd, F_SETFL, FNDELAY); before reading to get  the same result.  */  if (t->c_lflag & ICANON)    {      vmin_ = 0;      vtime_ = 0;    }  else    {      vtime_ = t->c_cc[VTIME] * 100;      vmin_ = t->c_cc[VMIN];    }  debug_printf ("vtime %d, vmin %d", vtime_, vmin_);  if (ovmin == vmin_ && ovtime == vtime_)    return 0;  memset (&to, 0, sizeof (to));  if ((vmin_ > 0) && (vtime_ == 0))    {      /* Returns immediately with whatever is in buffer on a ReadFile();	 or blocks if nothing found.  We will keep calling ReadFile(); until	 vmin_ characters are read */      to.ReadIntervalTimeout = to.ReadTotalTimeoutMultiplier = MAXDWORD;      to.ReadTotalTimeoutConstant = MAXDWORD - 1;    }  else if ((vmin_ == 0) && (vtime_ > 0))    {      /* set timeoout constant appropriately and we will only try to	 read one character in ReadFile() */      to.ReadTotalTimeoutConstant = vtime_;      to.ReadIntervalTimeout = to.ReadTotalTimeoutMultiplier = MAXDWORD;    }  else if ((vmin_ > 0) && (vtime_ > 0))    {      /* time applies to the interval time for this case */      to.ReadIntervalTimeout = vtime_;    }  else if ((vmin_ == 0) && (vtime_ == 0))    {      /* returns immediately with whatever is in buffer as per	 Time-Outs docs in Win32 SDK API docs */      to.ReadIntervalTimeout = MAXDWORD;    }  debug_printf ("ReadTotalTimeoutConstant %d, ReadIntervalTimeout %d, ReadTotalTimeoutMultiplier %d",		to.ReadTotalTimeoutConstant, to.ReadIntervalTimeout, to.ReadTotalTimeoutMultiplier);  int res = SetCommTimeouts (get_handle (), &to);  if (!res)    {      system_printf ("SetCommTimeout failed, %E");      __seterrno ();      return -1;    }  return 0;}/* tcgetattr: POSIX 7.2.1.1 */intfhandler_serial::tcgetattr (struct termios *t){  DCB state;  /* Get current Win32 comm state */  if (GetCommState (get_handle (), &state) == 0)    return -1;  /* for safety */  memset (t, 0, sizeof (*t));  /* -------------- Baud rate ------------------ */  switch (state.BaudRate)    {      case 0:	/* FIXME: need to drop DTR */	t->c_cflag = t->c_ospeed = t->c_ispeed = B0;	break;      case CBR_110:	t->c_cflag = t->c_ospeed = t->c_ispeed = B110;	break;      case CBR_300:	t->c_cflag = t->c_ospeed = t->c_ispeed = B300;	break;      case CBR_600:	t->c_cflag = t->c_ospeed = t->c_ispeed = B600;	break;      case CBR_1200:	t->c_cflag = t->c_ospeed = t->c_ispeed = B1200;	break;      case CBR_2400:	t->c_cflag = t->c_ospeed = t->c_ispeed = B2400;	break;      case CBR_4800:	t->c_cflag = t->c_ospeed = t->c_ispeed = B4800;	break;      case CBR_9600:	t->c_cflag = t->c_ospeed = t->c_ispeed = B9600;	break;      case CBR_19200:	t->c_cflag = t->c_ospeed = t->c_ispeed = B19200;	break;      case CBR_38400:	t->c_cflag = t->c_ospeed = t->c_ispeed = B38400;	break;      case CBR_57600:	t->c_cflag = t->c_ospeed = t->c_ispeed = B57600;	break;      case CBR_115200:	t->c_cflag = t->c_ospeed = t->c_ispeed = B115200;	break;      default:	/* Unsupported baud rate! */	termios_printf ("Invalid baud rate %d", state.BaudRate);	set_errno (EINVAL);	return -1;    }  /* -------------- Byte size ------------------ */  switch (state.ByteSize)    {      case 5:	t->c_cflag |= CS5;	break;      case 6:	t->c_cflag |= CS6;	break;      case 7:	t->c_cflag |= CS7;	break;      case 8:	t->c_cflag |= CS8;	break;      default:	/* Unsupported byte size! */	termios_printf ("Invalid byte size %d", state.ByteSize);	set_errno (EINVAL);	return -1;    }  /* -------------- Stop bits ------------------ */  if (state.StopBits == TWOSTOPBITS)    t->c_cflag |= CSTOPB;  /* -------------- Parity ------------------ */  if (state.Parity == ODDPARITY)    t->c_cflag |= (PARENB | PARODD);  if (state.Parity == EVENPARITY)    t->c_cflag |= PARENB;  /* -------------- Parity errors ------------------ */  /* fParity combines the function of INPCK and NOT IGNPAR */  if (state.fParity == TRUE)    t->c_iflag |= INPCK;  else    t->c_iflag |= IGNPAR;	/* not necessarily! */  /* -------------- Software flow control ------------------ */  /* transmission flow control */  if (state.fOutX)    t->c_iflag |= IXON;  /* reception flow control */  if (state.fInX)    t->c_iflag |= IXOFF;  t->c_cc[VSTART] = (state.XonChar ? state.XonChar : 0x11);  t->c_cc[VSTOP] = (state.XoffChar ? state.XoffChar : 0x13);  /* -------------- Hardware flow control ------------------ */  /* Some old flavors of Unix automatically enabled hardware flow     control when software flow control was not enabled.  Since newer     Unices tend to require explicit setting of hardware flow-control,     this is what we do. */  /* Input flow-control */  if ((state.fRtsControl == RTS_CONTROL_HANDSHAKE) &&      (state.fOutxCtsFlow == TRUE))    t->c_cflag |= CRTSCTS;  if (state.fRtsControl == RTS_CONTROL_HANDSHAKE)    t->c_cflag |= CRTSXOFF;  /* -------------- CLOCAL --------------- */  /* DSR is only lead toggled only by CLOCAL.  Check it to see if     CLOCAL was called. */  /* FIXME: If tcsetattr() hasn't been called previously, this may     give a false CLOCAL. */  if (state.fDsrSensitivity == FALSE)    t->c_cflag |= CLOCAL;  /* FIXME: need to handle IGNCR */#if 0  if (!get_r_binary ())    t->c_iflag |= IGNCR;#endif  if (!get_w_binary ())    t->c_oflag |= ONLCR;  t->c_cc[VTIME] = vtime_ / 100;  t->c_cc[VMIN] = vmin_;  debug_printf ("vmin_ %d, vtime_ %d", vmin_, vtime_);  return 0;}voidfhandler_serial::fixup_after_fork (HANDLE parent){  if (get_close_on_exec ())    this->fhandler_base::fixup_after_fork (parent);  overlapped_setup ();  debug_printf ("io_status.hEvent %p", io_status.hEvent);}voidfhandler_serial::fixup_after_exec (HANDLE){  overlapped_setup ();  debug_printf ("io_status.hEvent %p", io_status.hEvent);  return;}intfhandler_serial::dup (fhandler_base *child){  fhandler_serial *fhc = (fhandler_serial *) child;  overlapped_setup ();  fhc->vmin_ = vmin_;  fhc->vtime_ = vtime_;  return fhandler_base::dup (child);}

⌨️ 快捷键说明

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