3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
4 2006, 2007, 2008, 2009, 2011 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
20 #include <asm/socket.h>
21 #include <ddk/ntddser.h>
23 /**********************************************************************/
26 fhandler_serial::fhandler_serial ()
27 : fhandler_base (), vmin_ (0), vtime_ (0), pgrp_ (myself->pgid)
29 need_fork_fixup (true);
33 fhandler_serial::overlapped_setup ()
35 memset (&io_status, 0, sizeof (io_status));
36 io_status.hEvent = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
37 ProtectHandle (io_status.hEvent);
42 fhandler_serial::raw_read (void *ptr, size_t& ulen)
47 size_t minchars = vmin_ ? min (vmin_, ulen) : ulen;
49 debug_printf ("ulen %d, vmin_ %d, vtime_ %d, hEvent %p", ulen, vmin_, vtime_,
51 if (!overlapped_armed)
53 SetCommMask (get_handle (), EV_RXCHAR);
54 ResetEvent (io_status.hEvent);
57 for (n = 0, tot = 0; ulen; ulen -= n, ptr = (char *) ptr + n)
60 DWORD inq = vmin_ ? minchars : vtime_ ? ulen : 1;
64 if (vtime_) // non-interruptible -- have to use kernel timeouts
65 overlapped_armed = -1;
67 if (!ClearCommError (get_handle (), &ev, &st))
70 termios_printf ("error detected %x", ev);
71 else if (st.cbInQue && !vtime_)
73 else if (!overlapped_armed)
75 if ((size_t) tot >= minchars)
77 else if (WaitCommEvent (get_handle (), &ev, &io_status))
79 debug_printf ("WaitCommEvent succeeded: ev %x", ev);
83 else if (GetLastError () != ERROR_IO_PENDING)
85 else if (is_nonblocking ())
87 PurgeComm (get_handle (), PURGE_RXABORT);
98 switch (cygwait (io_status.hEvent))
101 if (!GetOverlappedResult (get_handle (), &io_status, &n,
104 debug_printf ("n %d, ev %x", n, ev);
106 case WAIT_OBJECT_0 + 1:
108 PurgeComm (get_handle (), PURGE_RXABORT);
109 overlapped_armed = 0;
110 set_sig_errno (EINTR);
112 case WAIT_OBJECT_0 + 2:
113 PurgeComm (get_handle (), PURGE_RXABORT);
114 overlapped_armed = 0;
115 pthread::static_cancel_self ();
123 overlapped_armed = 0;
124 ResetEvent (io_status.hEvent);
127 debug_printf ("inq %d", inq);
128 if (ReadFile (get_handle (), ptr, inq, &n, &io_status))
130 else if (GetLastError () != ERROR_IO_PENDING)
132 else if (is_nonblocking ())
134 PurgeComm (get_handle (), PURGE_RXABORT);
142 else if (!GetOverlappedResult (get_handle (), &io_status, &n, TRUE))
146 debug_printf ("vtime_ %d, vmin_ %d, n %d, tot %d", vtime_, vmin_, n, tot);
147 if (vtime_ || !vmin_ || !n)
152 debug_printf ("err %E");
153 if (GetLastError () != ERROR_OPERATION_ABORTED)
155 PurgeComm (get_handle (), PURGE_RXABORT);
168 /* Cover function to WriteFile to provide Posix interface and semantics
169 (as much as possible). */
171 fhandler_serial::raw_write (const void *ptr, size_t len)
174 OVERLAPPED write_status;
176 memset (&write_status, 0, sizeof (write_status));
177 write_status.hEvent = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
178 ProtectHandle (write_status.hEvent);
182 if (WriteFile (get_handle (), ptr, len, &bytes_written, &write_status))
185 switch (GetLastError ())
187 case ERROR_OPERATION_ABORTED:
189 if (!ClearCommError (get_handle (), &ev, NULL))
192 termios_printf ("error detected %x", ev);
194 case ERROR_IO_PENDING:
200 if (!is_nonblocking ())
202 switch (cygwait (write_status.hEvent))
206 case WAIT_OBJECT_0 + 1:
207 PurgeComm (get_handle (), PURGE_TXABORT);
208 set_sig_errno (EINTR);
209 ForceCloseHandle (write_status.hEvent);
211 case WAIT_OBJECT_0 + 2:
212 PurgeComm (get_handle (), PURGE_TXABORT);
213 pthread::static_cancel_self ();
219 if (!GetOverlappedResult (get_handle (), &write_status, &bytes_written, TRUE))
225 ForceCloseHandle (write_status.hEvent);
227 return bytes_written;
231 ForceCloseHandle (write_status.hEvent);
236 fhandler_serial::init (HANDLE f, DWORD flags, mode_t bin)
238 return open (flags, bin & (O_BINARY | O_TEXT));
242 fhandler_serial::open (int flags, mode_t mode)
246 extern BOOL reset_com;
248 syscall_printf ("fhandler_serial::open (%s, %p, %p)",
249 get_name (), flags, mode);
251 if (!fhandler_base::open (flags, mode))
256 SetCommMask (get_handle (), EV_RXCHAR);
260 memset (&to, 0, sizeof (to));
261 SetCommTimeouts (get_handle (), &to);
263 /* Reset serial port to known state of 9600-8-1-no flow control
264 on open for better behavior under Win 95.
266 FIXME: This should only be done when explicitly opening the com
267 port. It should not be reset if an fd is inherited.
268 Using __progname in this way, to determine how far along in the
269 initialization we are, is really a terrible kludge and should
272 if (reset_com && __progname)
275 GetCommState (get_handle (), &state);
276 syscall_printf ("setting initial state on %s (reset_com %d)",
277 get_name (), reset_com);
278 state.BaudRate = CBR_9600;
280 state.StopBits = ONESTOPBIT;
281 state.Parity = NOPARITY; /* FIXME: correct default? */
282 state.fBinary = TRUE; /* binary xfer */
283 state.EofChar = 0; /* no end-of-data in binary mode */
284 state.fNull = FALSE; /* don't discard nulls in binary mode */
285 state.fParity = FALSE; /* ignore parity errors */
286 state.fErrorChar = FALSE;
287 state.fTXContinueOnXoff = TRUE; /* separate TX and RX flow control */
288 state.fOutX = FALSE; /* disable transmission flow control */
289 state.fInX = FALSE; /* disable reception flow control */
290 state.XonChar = 0x11;
291 state.XoffChar = 0x13;
292 state.fOutxDsrFlow = FALSE; /* disable DSR flow control */
293 state.fRtsControl = RTS_CONTROL_ENABLE; /* ignore lead control except
295 state.fOutxCtsFlow = FALSE; /* disable output flow control */
296 state.fDtrControl = DTR_CONTROL_ENABLE; /* assert DTR */
297 state.fDsrSensitivity = FALSE; /* don't assert DSR */
298 state.fAbortOnError = TRUE;
299 if (!SetCommState (get_handle (), &state))
300 system_printf ("couldn't set initial state for %s, %E", get_name ());
303 SetCommMask (get_handle (), EV_RXCHAR);
305 syscall_printf ("%p = fhandler_serial::open (%s, %p, %p)",
306 res, get_name (), flags, mode);
311 fhandler_serial::close ()
313 ForceCloseHandle (io_status.hEvent);
314 return fhandler_base::close ();
317 /* tcsendbreak: POSIX 7.2.2.1 */
318 /* Break for 250-500 milliseconds if duration == 0 */
319 /* Otherwise, units for duration are undefined */
321 fhandler_serial::tcsendbreak (int duration)
323 unsigned int sleeptime = 300000;
326 sleeptime *= duration;
328 if (SetCommBreak (get_handle ()) == 0)
331 /* FIXME: need to send zero bits during duration */
334 if (ClearCommBreak (get_handle ()) == 0)
337 syscall_printf ("0 = fhandler_serial:tcsendbreak (%d)", duration);
342 /* tcdrain: POSIX 7.2.2.1 */
344 fhandler_serial::tcdrain ()
346 if (FlushFileBuffers (get_handle ()) == 0)
352 /* tcflow: POSIX 7.2.2.1 */
354 fhandler_serial::tcflow (int action)
356 DWORD win32action = 0;
360 termios_printf ("action %d", action);
365 win32action = SETXOFF;
368 win32action = SETXON;
372 if (GetCommState (get_handle (), &dcb) == 0)
375 xchar = (dcb.XonChar ? dcb.XonChar : 0x11);
377 xchar = (dcb.XoffChar ? dcb.XoffChar : 0x13);
378 if (TransmitCommChar (get_handle (), xchar) == 0)
387 if (EscapeCommFunction (get_handle (), win32action) == 0)
394 /* switch_modem_lines: set or clear RTS and/or DTR */
396 fhandler_serial::switch_modem_lines (int set, int clr)
402 if (EscapeCommFunction (get_handle (), SETRTS))
410 else if (clr & TIOCM_RTS)
412 if (EscapeCommFunction (get_handle (), CLRRTS))
422 if (EscapeCommFunction (get_handle (), SETDTR))
430 else if (clr & TIOCM_DTR)
432 if (EscapeCommFunction (get_handle (), CLRDTR))
446 fhandler_serial::ioctl (unsigned int cmd, void *buf)
450 # define ibuf ((int) buf)
451 # define ipbuf (*(int *) buf)
455 if (!ClearCommError (get_handle (), &ev, &st))
464 res = tcflush (ibuf);
468 if (!GetCommModemStatus (get_handle (), &modem_lines))
476 if (modem_lines & MS_CTS_ON)
478 if (modem_lines & MS_DSR_ON)
480 if (modem_lines & MS_RING_ON)
482 if (modem_lines & MS_RLSD_ON)
487 if (!DeviceIoControl (get_handle (), IOCTL_SERIAL_GET_DTRRTS,
488 NULL, 0, &mcr, 4, &cb, 0) || cb != 4)
500 if (switch_modem_lines (ipbuf, ~ipbuf))
504 if (switch_modem_lines (ipbuf, 0))
508 if (switch_modem_lines (0, ipbuf))
512 if (ClearCommBreak (get_handle ()) == 0)
519 if (SetCommBreak (get_handle ()) == 0)
526 if (ev & CE_FRAME || ev & CE_IOE || ev & CE_OVERRUN || ev & CE_RXOVER
529 set_errno (EINVAL); /* FIXME: Use correct errno */
536 ((struct winsize *) buf)->ws_row = 0;
537 ((struct winsize *) buf)->ws_col = 0;
544 res = fhandler_base::ioctl (cmd, buf);
548 termios_printf ("%d = ioctl(%p, %p)", res, cmd, buf);
554 /* tcflush: POSIX 7.2.2.1 */
556 fhandler_serial::tcflush (int queue)
563 flags = PURGE_TXABORT | PURGE_TXCLEAR;
566 flags = PURGE_RXABORT | PURGE_RXCLEAR;
569 flags = PURGE_TXABORT | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_RXCLEAR;
572 termios_printf ("Invalid tcflush queue %d", queue);
577 if (!PurgeComm (get_handle (), flags))
586 /* tcsetattr: POSIX 7.2.1.1 */
588 fhandler_serial::tcsetattr (int action, const struct termios *t)
591 TCSANOW: immediately change attributes.
592 TCSADRAIN: flush output, then change attributes.
593 TCSAFLUSH: flush output and discard input, then change attributes.
596 bool dropDTR = false;
599 unsigned int ovtime = vtime_, ovmin = vmin_;
600 int tmpDtr, tmpRts, res;
601 res = tmpDtr = tmpRts = 0;
603 termios_printf ("action %d", action);
604 if ((action == TCSADRAIN) || (action == TCSAFLUSH))
606 FlushFileBuffers (get_handle ());
607 termios_printf ("flushed file buffers");
609 if (action == TCSAFLUSH)
610 PurgeComm (get_handle (), (PURGE_RXABORT | PURGE_RXCLEAR));
612 /* get default/last comm state */
613 if (!GetCommState (get_handle (), &ostate))
618 /* -------------- Set baud rate ------------------ */
619 /* FIXME: WIN32 also has 14400, 56000, 128000, and 256000.
620 Unix also has 230400. */
625 /* Drop DTR - but leave DCB-resident bitrate as-is since
626 0 is an invalid bitrate in Win32 */
630 state.BaudRate = CBR_110;
633 state.BaudRate = CBR_300;
636 state.BaudRate = CBR_600;
639 state.BaudRate = CBR_1200;
642 state.BaudRate = CBR_2400;
645 state.BaudRate = CBR_4800;
648 state.BaudRate = CBR_9600;
651 state.BaudRate = CBR_19200;
654 state.BaudRate = CBR_38400;
657 state.BaudRate = CBR_57600;
660 state.BaudRate = CBR_115200;
663 state.BaudRate = CBR_128000;
666 state.BaudRate = 230400 /* CBR_230400 - not defined */;
669 state.BaudRate = CBR_256000;
672 state.BaudRate = 460800 /* CBR_460800 - not defined */;
675 state.BaudRate = 500000 /* CBR_500000 - not defined */;
678 state.BaudRate = 576000 /* CBR_576000 - not defined */;
681 state.BaudRate = 921600 /* CBR_921600 - not defined */;
684 state.BaudRate = 1000000 /* CBR_1000000 - not defined */;
687 state.BaudRate = 1152000 /* CBR_1152000 - not defined */;
690 state.BaudRate = 1500000 /* CBR_1500000 - not defined */;
693 state.BaudRate = 2000000 /* CBR_2000000 - not defined */;
696 state.BaudRate = 2500000 /* CBR_2500000 - not defined */;
699 state.BaudRate = 3000000 /* CBR_3000000 - not defined */;
702 /* Unsupported baud rate! */
703 termios_printf ("Invalid t->c_ospeed %d", t->c_ospeed);
708 /* -------------- Set byte size ------------------ */
710 switch (t->c_cflag & CSIZE)
725 /* Unsupported byte size! */
726 termios_printf ("Invalid t->c_cflag byte size %d",
732 /* -------------- Set stop bits ------------------ */
734 if (t->c_cflag & CSTOPB)
735 state.StopBits = TWOSTOPBITS;
737 state.StopBits = ONESTOPBIT;
739 /* -------------- Set parity ------------------ */
741 if (t->c_cflag & PARENB)
742 state.Parity = (t->c_cflag & PARODD) ? ODDPARITY : EVENPARITY;
744 state.Parity = NOPARITY;
746 state.fBinary = TRUE; /* Binary transfer */
747 state.EofChar = 0; /* No end-of-data in binary mode */
748 state.fNull = FALSE; /* Don't discard nulls in binary mode */
750 /* -------------- Parity errors ------------------ */
751 /* fParity combines the function of INPCK and NOT IGNPAR */
753 if ((t->c_iflag & INPCK) && !(t->c_iflag & IGNPAR))
754 state.fParity = TRUE; /* detect parity errors */
756 state.fParity = FALSE; /* ignore parity errors */
758 /* Only present in Win32, Unix has no equivalent */
759 state.fErrorChar = FALSE;
762 /* -------------- Set software flow control ------------------ */
763 /* Set fTXContinueOnXoff to FALSE. This prevents the triggering of a
764 premature XON when the remote device interprets a received character
765 as XON (same as IXANY on the remote side). Otherwise, a TRUE
766 value separates the TX and RX functions. */
768 state.fTXContinueOnXoff = TRUE; /* separate TX and RX flow control */
770 /* Transmission flow control */
771 if (t->c_iflag & IXON)
772 state.fOutX = TRUE; /* enable */
774 state.fOutX = FALSE; /* disable */
776 /* Reception flow control */
777 if (t->c_iflag & IXOFF)
778 state.fInX = TRUE; /* enable */
780 state.fInX = FALSE; /* disable */
782 /* XoffLim and XonLim are left at default values */
784 state.XonChar = (t->c_cc[VSTART] ? t->c_cc[VSTART] : 0x11);
785 state.XoffChar = (t->c_cc[VSTOP] ? t->c_cc[VSTOP] : 0x13);
787 /* -------------- Set hardware flow control ------------------ */
789 /* Disable DSR flow control */
790 state.fOutxDsrFlow = FALSE;
792 /* Some old flavors of Unix automatically enabled hardware flow
793 control when software flow control was not enabled. Since newer
794 Unices tend to require explicit setting of hardware flow-control,
795 this is what we do. */
797 /* RTS/CTS flow control */
798 if (t->c_cflag & CRTSCTS)
800 state.fOutxCtsFlow = TRUE;
801 state.fRtsControl = RTS_CONTROL_HANDSHAKE;
805 state.fRtsControl = RTS_CONTROL_ENABLE;
806 state.fOutxCtsFlow = FALSE;
810 if (t->c_cflag & CRTSXOFF)
811 state.fRtsControl = RTS_CONTROL_HANDSHAKE;
813 /* -------------- DTR ------------------ */
814 /* Assert DTR on device open */
816 state.fDtrControl = DTR_CONTROL_ENABLE;
818 /* -------------- DSR ------------------ */
819 /* Assert DSR at the device? */
821 if (t->c_cflag & CLOCAL)
822 state.fDsrSensitivity = FALSE; /* no */
824 state.fDsrSensitivity = TRUE; /* yes */
826 /* -------------- Error handling ------------------ */
827 /* Since read/write operations terminate upon error, we
828 will use ClearCommError() to resume. */
830 state.fAbortOnError = TRUE;
832 if ((memcmp (&ostate, &state, sizeof (state)) != 0)
833 && !SetCommState (get_handle (), &state))
835 /* SetCommState() failed, usually due to invalid DCB param.
836 Keep track of this so we can set errno to EINVAL later
837 and return failure */
838 termios_printf ("SetCommState() failed, %E");
843 rbinary ((t->c_iflag & IGNCR) ? false : true);
844 wbinary ((t->c_oflag & ONLCR) ? false : true);
848 EscapeCommFunction (get_handle (), CLRDTR);
853 /* FIXME: Sometimes when CLRDTR is set, setting
854 state.fDtrControl = DTR_CONTROL_ENABLE will fail. This
855 is a problem since a program might want to change some
856 parameters while DTR is still down. */
858 EscapeCommFunction (get_handle (), SETDTR);
865 /* The following documentation on was taken from "Linux Serial Programming
866 HOWTO". It explains how MIN (t->c_cc[VMIN] || vmin_) and TIME
867 (t->c_cc[VTIME] || vtime_) is to be used.
869 In non-canonical input processing mode, input is not assembled into
870 lines and input processing (erase, kill, delete, etc.) does not
871 occur. Two parameters control the behavior of this mode: c_cc[VTIME]
872 sets the character timer, and c_cc[VMIN] sets the minimum number of
873 characters to receive before satisfying the read.
875 If MIN > 0 and TIME = 0, MIN sets the number of characters to receive
876 before the read is satisfied. As TIME is zero, the timer is not used.
878 If MIN = 0 and TIME > 0, TIME serves as a timeout value. The read will
879 be satisfied if a single character is read, or TIME is exceeded (t =
880 TIME *0.1 s). If TIME is exceeded, no character will be returned.
882 If MIN > 0 and TIME > 0, TIME serves as an inter-character timer. The
883 read will be satisfied if MIN characters are received, or the time
884 between two characters exceeds TIME. The timer is restarted every time
885 a character is received and only becomes active after the first
886 character has been received.
888 If MIN = 0 and TIME = 0, read will be satisfied immediately. The
889 number of characters currently available, or the number of characters
890 requested will be returned. According to Antonino (see contributions),
891 you could issue a fcntl(fd, F_SETFL, FNDELAY); before reading to get
895 if (t->c_lflag & ICANON)
902 vtime_ = t->c_cc[VTIME] * 100;
903 vmin_ = t->c_cc[VMIN];
906 debug_printf ("vtime %d, vmin %d", vtime_, vmin_);
908 if (ovmin != vmin_ || ovtime != vtime_)
910 memset (&to, 0, sizeof (to));
912 if ((vmin_ > 0) && (vtime_ == 0))
914 /* Returns immediately with whatever is in buffer on a ReadFile();
915 or blocks if nothing found. We will keep calling ReadFile(); until
916 vmin_ characters are read */
917 to.ReadIntervalTimeout = to.ReadTotalTimeoutMultiplier = MAXDWORD;
918 to.ReadTotalTimeoutConstant = MAXDWORD - 1;
920 else if ((vmin_ == 0) && (vtime_ > 0))
922 /* set timeoout constant appropriately and we will only try to
923 read one character in ReadFile() */
924 to.ReadTotalTimeoutConstant = vtime_;
925 to.ReadIntervalTimeout = to.ReadTotalTimeoutMultiplier = MAXDWORD;
927 else if ((vmin_ > 0) && (vtime_ > 0))
929 /* time applies to the interval time for this case */
930 to.ReadIntervalTimeout = vtime_;
932 else if ((vmin_ == 0) && (vtime_ == 0))
934 /* returns immediately with whatever is in buffer as per
935 Time-Outs docs in Win32 SDK API docs */
936 to.ReadIntervalTimeout = MAXDWORD;
939 debug_printf ("ReadTotalTimeoutConstant %d, ReadIntervalTimeout %d, ReadTotalTimeoutMultiplier %d",
940 to.ReadTotalTimeoutConstant, to.ReadIntervalTimeout, to.ReadTotalTimeoutMultiplier);
942 if (!SetCommTimeouts(get_handle (), &to))
944 /* SetCommTimeouts() failed. Keep track of this so we
945 can set errno to EINVAL later and return failure */
946 termios_printf ("SetCommTimeouts() failed, %E");
955 /* tcgetattr: POSIX 7.2.1.1 */
957 fhandler_serial::tcgetattr (struct termios *t)
961 /* Get current Win32 comm state */
962 if (GetCommState (get_handle (), &state) == 0)
966 memset (t, 0, sizeof (*t));
969 /* -------------- Baud rate ------------------ */
970 switch (state.BaudRate)
973 t->c_ospeed = t->c_ispeed = B110;
976 t->c_ospeed = t->c_ispeed = B300;
979 t->c_ospeed = t->c_ispeed = B600;
982 t->c_ospeed = t->c_ispeed = B1200;
985 t->c_ospeed = t->c_ispeed = B2400;
988 t->c_ospeed = t->c_ispeed = B4800;
991 t->c_ospeed = t->c_ispeed = B9600;
994 t->c_ospeed = t->c_ispeed = B19200;
997 t->c_ospeed = t->c_ispeed = B38400;
1000 t->c_ospeed = t->c_ispeed = B57600;
1003 t->c_ospeed = t->c_ispeed = B115200;
1006 t->c_ospeed = t->c_ispeed = B128000;
1008 case 230400: /* CBR_230400 - not defined */
1009 t->c_ospeed = t->c_ispeed = B230400;
1012 t->c_ospeed = t->c_ispeed = B256000;
1014 case 460800: /* CBR_460000 - not defined */
1015 t->c_ospeed = t->c_ispeed = B460800;
1017 case 500000: /* CBR_500000 - not defined */
1018 t->c_ospeed = t->c_ispeed = B500000;
1020 case 576000: /* CBR_576000 - not defined */
1021 t->c_ospeed = t->c_ispeed = B576000;
1023 case 921600: /* CBR_921600 - not defined */
1024 t->c_ospeed = t->c_ispeed = B921600;
1026 case 1000000: /* CBR_1000000 - not defined */
1027 t->c_ospeed = t->c_ispeed = B1000000;
1029 case 1152000: /* CBR_1152000 - not defined */
1030 t->c_ospeed = t->c_ispeed = B1152000;
1032 case 1500000: /* CBR_1500000 - not defined */
1033 t->c_ospeed = t->c_ispeed = B1500000;
1035 case 2000000: /* CBR_2000000 - not defined */
1036 t->c_ospeed = t->c_ispeed = B2000000;
1038 case 2500000: /* CBR_2500000 - not defined */
1039 t->c_ospeed = t->c_ispeed = B2500000;
1041 case 3000000: /* CBR_3000000 - not defined */
1042 t->c_ospeed = t->c_ispeed = B3000000;
1045 /* Unsupported baud rate! */
1046 termios_printf ("Invalid baud rate %d", state.BaudRate);
1051 /* -------------- Byte size ------------------ */
1053 switch (state.ByteSize)
1068 /* Unsupported byte size! */
1069 termios_printf ("Invalid byte size %d", state.ByteSize);
1074 /* -------------- Stop bits ------------------ */
1076 if (state.StopBits == TWOSTOPBITS)
1077 t->c_cflag |= CSTOPB;
1079 /* -------------- Parity ------------------ */
1081 if (state.Parity == ODDPARITY)
1082 t->c_cflag |= (PARENB | PARODD);
1083 if (state.Parity == EVENPARITY)
1084 t->c_cflag |= PARENB;
1086 /* -------------- Parity errors ------------------ */
1088 /* fParity combines the function of INPCK and NOT IGNPAR */
1090 t->c_iflag |= INPCK;
1092 t->c_iflag |= IGNPAR; /* not necessarily! */
1094 /* -------------- Software flow control ------------------ */
1096 /* transmission flow control */
1100 /* reception flow control */
1102 t->c_iflag |= IXOFF;
1104 t->c_cc[VSTART] = (state.XonChar ? state.XonChar : 0x11);
1105 t->c_cc[VSTOP] = (state.XoffChar ? state.XoffChar : 0x13);
1107 /* -------------- Hardware flow control ------------------ */
1108 /* Some old flavors of Unix automatically enabled hardware flow
1109 control when software flow control was not enabled. Since newer
1110 Unices tend to require explicit setting of hardware flow-control,
1111 this is what we do. */
1113 /* Input flow-control */
1114 if ((state.fRtsControl == RTS_CONTROL_HANDSHAKE) && state.fOutxCtsFlow)
1115 t->c_cflag |= CRTSCTS;
1116 if (state.fRtsControl == RTS_CONTROL_HANDSHAKE)
1117 t->c_cflag |= CRTSXOFF;
1119 /* -------------- CLOCAL --------------- */
1120 /* DSR is only lead toggled only by CLOCAL. Check it to see if
1121 CLOCAL was called. */
1122 /* FIXME: If tcsetattr() hasn't been called previously, this may
1123 give a false CLOCAL. */
1125 if (!state.fDsrSensitivity)
1126 t->c_cflag |= CLOCAL;
1128 /* FIXME: need to handle IGNCR */
1131 t->c_iflag |= IGNCR;
1135 t->c_oflag |= ONLCR;
1137 t->c_cc[VTIME] = vtime_ / 100;
1138 t->c_cc[VMIN] = vmin_;
1140 debug_printf ("vmin_ %d, vtime_ %d", vmin_, vtime_);
1146 fhandler_serial::fixup_after_fork (HANDLE parent)
1148 if (close_on_exec ())
1149 fhandler_base::fixup_after_fork (parent);
1150 overlapped_setup ();
1151 debug_printf ("io_status.hEvent %p", io_status.hEvent);
1155 fhandler_serial::fixup_after_exec ()
1157 if (!close_on_exec ())
1158 overlapped_setup ();
1159 debug_printf ("io_status.hEvent %p, close_on_exec %d", io_status.hEvent, close_on_exec ());
1163 fhandler_serial::dup (fhandler_base *child, int flags)
1165 fhandler_serial *fhc = (fhandler_serial *) child;
1166 fhc->overlapped_setup ();
1167 return fhandler_base::dup (child, flags);