Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/fhandler_serial.cc')
-rw-r--r--winsup/cygwin/fhandler_serial.cc883
1 files changed, 0 insertions, 883 deletions
diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc
deleted file mode 100644
index de4c7fedd..000000000
--- a/winsup/cygwin/fhandler_serial.cc
+++ /dev/null
@@ -1,883 +0,0 @@
-/* fhandler_serial.cc
-
- Copyright 1996, 1997, 1998, 1999, 2000 Cygnus Solutions.
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include "winsup.h"
-
-/**********************************************************************/
-/* fhandler_serial */
-
-fhandler_serial::fhandler_serial (const char *name, DWORD devtype, int unit) :
- fhandler_base (devtype, name, unit)
-{
- set_cb (sizeof *this);
- vmin_ = 0;
- vtime_ = 0;
- pgrp_ = myself->pgid;
- set_need_fork_fixup ();
-}
-
-void
-fhandler_serial::overlapped_setup ()
-{
- memset (&io_status, 0, sizeof (io_status));
- io_status.hEvent = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
- ProtectHandle (io_status.hEvent);
- overlapped_armed = 0;
-}
-
-int
-fhandler_serial::raw_read (void *ptr, size_t ulen)
-{
- int tot;
- DWORD n;
- HANDLE w4[2];
- DWORD minchars = vmin_ ?: ulen;
-
- w4[0] = io_status.hEvent;
- w4[1] = signal_arrived;
-
- debug_printf ("ulen %d, vmin_ %d, vtime_ %d, hEvent %p", ulen, vmin_, vtime_,
- io_status.hEvent);
- if (!overlapped_armed)
- {
- (void) SetCommMask (get_handle (), EV_RXCHAR);
- ResetEvent (io_status.hEvent);
- }
-
- for (n = 0, tot = 0; ulen; ulen -= n, ptr = (char *)ptr + n)
- {
- DWORD ev;
- COMSTAT st;
- DWORD inq = 1;
-
- n = 0;
-
- if (!vtime_ && !vmin_)
- inq = ulen;
- else if (vtime_)
- {
- inq = ulen; // non-interruptible -- have to use kernel timeouts
- // also note that this is not strictly correct.
- // if vmin > ulen then things won't work right.
- overlapped_armed = -1;
- }
- if (!overlapped_armed)
- {
- if (!ClearCommError (get_handle (), &ev, &st))
- goto err;
- else if (ev)
- termios_printf ("error detected %x", ev);
- else if (st.cbInQue)
- inq = st.cbInQue;
- else if ((size_t)tot >= minchars)
- break;
- else if (WaitCommEvent (get_handle (), &ev, &io_status))
- {
- debug_printf ("WaitCommEvent succeeded: ev %x", ev);
- if (!ev)
- continue;
- }
- else if (GetLastError () != ERROR_IO_PENDING)
- goto err;
- else
- {
- overlapped_armed = 1;
- switch (WaitForMultipleObjects (2, w4, FALSE, INFINITE))
- {
- case WAIT_OBJECT_0:
- if (!GetOverlappedResult (get_handle (), &io_status, &n, FALSE))
- goto err;
- debug_printf ("n %d, ev %x", n, ev);
- break;
- case WAIT_OBJECT_0 + 1:
- tot = -1;
- PurgeComm (get_handle (), PURGE_RXABORT);
- overlapped_armed = 0;
- set_sig_errno (EINTR);
- goto out;
- default:
- goto err;
- }
- }
- }
-
- overlapped_armed = 0;
- ResetEvent (io_status.hEvent);
- if (inq > ulen)
- inq = ulen;
- debug_printf ("inq %d", inq);
- if (ReadFile (get_handle(), ptr, min (inq, ulen), &n, &io_status))
- /* Got something */;
- else if (GetLastError () != ERROR_IO_PENDING)
- goto err;
- else if (!GetOverlappedResult (get_handle (), &io_status, &n, TRUE))
- goto err;
-
- tot += n;
- debug_printf ("vtime_ %d, vmin_ %d, n %d, tot %d", vtime_, vmin_, n, tot);
- if (vtime_ || !vmin_ || !n)
- break;
- continue;
-
- err:
- PurgeComm (get_handle (), PURGE_RXABORT);
- debug_printf ("err %E");
- if (GetLastError () == ERROR_OPERATION_ABORTED)
- n = 0;
- else
- {
- tot = -1;
- __seterrno ();
- break;
- }
- }
-
-out:
- return tot;
-}
-
-/* Cover function to WriteFile to provide Posix interface and semantics
- (as much as possible). */
-int
-fhandler_serial::raw_write (const void *ptr, size_t len)
-{
- DWORD bytes_written;
-
- if (overlapped_armed)
- PurgeComm (get_handle (), PURGE_TXABORT | PURGE_RXABORT);
- ResetEvent (io_status.hEvent);
-
- for (;;)
- {
- overlapped_armed = TRUE;
- if (WriteFile (get_handle(), ptr, len, &bytes_written, &io_status))
- break;
-
- switch (GetLastError ())
- {
- case ERROR_OPERATION_ABORTED:
- continue;
- case ERROR_IO_PENDING:
- break;
- default:
- goto err;
- }
-
- if (!GetOverlappedResult (get_handle (), &io_status, &bytes_written, TRUE))
- goto err;
-
- break;
- }
-
- overlapped_armed = FALSE;
- return bytes_written;
-
-err:
- __seterrno ();
- return -1;
-}
-
-void
-fhandler_serial::dump (void)
-{
- paranoid_printf ("here");
-}
-
-void
-fhandler_serial::init (HANDLE f, DWORD flags, mode_t bin)
-{
- fhandler_base::init (f, flags, bin);
- (void) open (NULL, flags, bin ? O_BINARY : 0);
-}
-
-int
-fhandler_serial::open (const char *name, int flags, mode_t mode)
-{
- int res;
- COMMTIMEOUTS to;
- extern BOOL reset_com;
-
- syscall_printf ("fhandler_serial::open (%s, %p, %p)",
- get_name (), flags, mode);
-
- if (name && !(res = this->fhandler_base::open (flags, mode)))
- return 0;
- else
- res = 1;
-
- (void) SetCommMask (get_handle (), EV_RXCHAR);
-
- set_r_no_interrupt (1); // Handled explicitly in read code
-
- overlapped_setup ();
-
- memset (&to, 0, sizeof (to));
- (void) SetCommTimeouts (get_handle (), &to);
-
- /* Reset serial port to known state of 9600-8-1-no flow control
- on open for better behavior under Win 95.
-
- FIXME: This should only be done when explicitly opening the com
- port. It should not be reset if an fd is inherited.
- Using __progname in this way, to determine how far along in the
- initialization we are, is really a terrible kludge and should
- be fixed ASAP.
- */
- extern char *__progname;
- if (reset_com && __progname)
- {
- DCB state;
- GetCommState (get_handle (), &state);
- syscall_printf ("setting initial state on %s (reset_com %d)",
- get_name (), reset_com);
- state.BaudRate = CBR_9600;
- state.ByteSize = 8;
- state.StopBits = ONESTOPBIT;
- state.Parity = NOPARITY; /* FIXME: correct default? */
- state.fBinary = TRUE; /* binary xfer */
- state.EofChar = 0; /* no end-of-data in binary mode */
- state.fNull = FALSE; /* don't discard nulls in binary mode */
- state.fParity = FALSE; /* ignore parity errors */
- state.fErrorChar = FALSE;
- state.fTXContinueOnXoff = TRUE; /* separate TX and RX flow control */
- state.fOutX = FALSE; /* disable transmission flow control */
- state.fInX = FALSE; /* disable reception flow control */
- state.XonChar = 0x11;
- state.XoffChar = 0x13;
- state.fOutxDsrFlow = FALSE; /* disable DSR flow control */
- state.fRtsControl = RTS_CONTROL_ENABLE; /* ignore lead control except
- DTR */
- state.fOutxCtsFlow = FALSE; /* disable output flow control */
- state.fDtrControl = DTR_CONTROL_ENABLE; /* assert DTR */
- state.fDsrSensitivity = FALSE; /* don't assert DSR */
- state.fAbortOnError = TRUE;
- if (!SetCommState (get_handle (), &state))
- system_printf ("couldn't set initial state for %s, %E", get_name ());
- }
-
- SetCommMask (get_handle (), EV_RXCHAR);
- syscall_printf ("%p = fhandler_serial::open (%s, %p, %p)",
- res, get_name (), flags, mode);
- return res;
-}
-
-int
-fhandler_serial::close ()
-{
- (void) ForceCloseHandle (io_status.hEvent);
- return fhandler_base::close ();
-}
-
-/* tcsendbreak: POSIX 7.2.2.1 */
-/* Break for 250-500 milliseconds if duration == 0 */
-/* Otherwise, units for duration are undefined */
-int
-fhandler_serial::tcsendbreak (int duration)
-{
- unsigned int sleeptime = 300;
-
- if (duration > 0)
- sleeptime *= duration;
-
- if (SetCommBreak (get_handle ()) == 0)
- return -1;
-
- /* FIXME: need to send zero bits during duration */
- usleep (sleeptime);
-
- if (ClearCommBreak (get_handle ()) == 0)
- return -1;
-
- syscall_printf ("0 = fhandler_serial:tcsendbreak (%d)", duration);
-
- return 0;
-}
-
-/* tcdrain: POSIX 7.2.2.1 */
-int
-fhandler_serial::tcdrain (void)
-{
- if (FlushFileBuffers (get_handle ()) == 0)
- return -1;
-
- return 0;
-}
-
-/* tcflow: POSIX 7.2.2.1 */
-int
-fhandler_serial::tcflow (int action)
-{
- DWORD win32action = 0;
- DCB dcb;
- char xchar;
-
- termios_printf ("action %d", action);
-
- switch (action)
- {
- case TCOOFF:
- win32action = SETXOFF;
- break;
- case TCOON:
- win32action = SETXON;
- break;
- case TCION:
- case TCIOFF:
- if (GetCommState (get_handle (), &dcb) == 0)
- return -1;
- if (action == TCION)
- xchar = (dcb.XonChar ? dcb.XonChar : 0x11);
- else
- xchar = (dcb.XoffChar ? dcb.XoffChar : 0x13);
- if (TransmitCommChar (get_handle (), xchar) == 0)
- return -1;
- return 0;
- break;
- default:
- return -1;
- break;
- }
-
- if (EscapeCommFunction (get_handle (), win32action) == 0)
- return -1;
-
- return 0;
-}
-
-/* tcflush: POSIX 7.2.2.1 */
-int
-fhandler_serial::tcflush (int queue)
-{
- if (queue == TCOFLUSH || queue == TCIOFLUSH)
- PurgeComm (get_handle (), PURGE_TXABORT | PURGE_TXCLEAR);
-
- if (queue == TCIFLUSH | queue == TCIOFLUSH)
- /* Input flushing by polling until nothing turns up
- (we stop after 1000 chars anyway) */
- for (int max = 1000; max > 0; max--)
- {
- DWORD ev;
- COMSTAT st;
- if (!PurgeComm (get_handle (), PURGE_RXABORT | PURGE_RXCLEAR))
- break;
- Sleep (100);
- if (!ClearCommError (get_handle (), &ev, &st) || !st.cbInQue)
- break;
- }
-
- return 0;
-}
-
-/* tcsetattr: POSIX 7.2.1.1 */
-int
-fhandler_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_;
-
- 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;
- }
-
- 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);
- 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);
- }
-
- /*
- 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_ = MAXDWORD;
- vtime_ = 0;
- }
- else
- {
- vtime_ = t->c_cc[VTIME] * 100;
- vmin_ = t->c_cc[VMIN];
- }
-
- debug_printf ("vtime %d, vmin %d\n", 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 */
-int
-fhandler_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;
-
- debug_printf ("vmin_ %d, vtime_ %d", vmin_, vtime_);
- if (vmin_ == MAXDWORD)
- {
- t->c_lflag |= ICANON;
- t->c_cc[VTIME] = t->c_cc[VMIN] = 0;
- }
- else
- {
- t->c_cc[VTIME] = vtime_ / 100;
- t->c_cc[VMIN] = vmin_;
- }
-
- return 0;
-}
-
-void
-fhandler_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);
-}
-
-int
-fhandler_serial::de_linearize (const char *buf, const char *unix_name,
- const char *win32_name)
-{
- int res = fhandler_base::de_linearize (buf, unix_name, win32_name);
- overlapped_setup ();
- debug_printf ("io_status.hEvent %p", io_status.hEvent);
- return res;
-}
-
-int
-fhandler_serial::dup (fhandler_base *child)
-{
- fhandler_serial *fhc = (fhandler_serial *) child;
- overlapped_setup ();
- fhc->vmin_ = vmin_;
- fhc->vtime_ = vtime_;
- return fhandler_base::dup (child);
-}