diff options
Diffstat (limited to 'winsup/cygwin/fhandler_serial.cc')
-rw-r--r-- | winsup/cygwin/fhandler_serial.cc | 1003 |
1 files changed, 0 insertions, 1003 deletions
diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc deleted file mode 100644 index 748eb4b..0000000 --- a/winsup/cygwin/fhandler_serial.cc +++ /dev/null @@ -1,1003 +0,0 @@ -/* fhandler_serial.cc - - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. - -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 "winsup.h" -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include "cygerrno.h" -#include "security.h" -#include "fhandler.h" -#include "sigproc.h" -#include "pinfo.h" -#include <sys/termios.h> - -/**********************************************************************/ -/* fhandler_serial */ - -fhandler_serial::fhandler_serial (int unit) - : fhandler_base (FH_SERIAL, unit), 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) - { - 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 (!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 (!overlapped_armed) - { - 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; - OVERLAPPED write_status; - - memset (&write_status, 0, sizeof (write_status)); - write_status.hEvent = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL); - ProtectHandle (write_status.hEvent); - - for (;;) - { - if (WriteFile (get_handle (), ptr, len, &bytes_written, &write_status)) - break; - - switch (GetLastError ()) - { - case ERROR_OPERATION_ABORTED: - continue; - case ERROR_IO_PENDING: - break; - default: - goto err; - } - - if (!GetOverlappedResult (get_handle (), &write_status, &bytes_written, TRUE)) - goto err; - - break; - } - - ForceCloseHandle (write_status.hEvent); - - return bytes_written; - -err: - __seterrno (); - ForceCloseHandle (write_status.hEvent); - return -1; -} - -void -fhandler_serial::dump (void) -{ - paranoid_printf ("here"); -} - -void -fhandler_serial::init (HANDLE f, DWORD flags, mode_t bin) -{ - (void) open (NULL, flags, bin & (O_BINARY | O_TEXT)); -} - -int -fhandler_serial::open (path_conv *, 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 (!(res = this->fhandler_base::open (NULL, flags, mode))) - return 0; - - 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 ()); - } - - /* setting rts and dtr to known state so that ioctl() function with - request TIOCMGET could return correct value of RTS and DTR lines. - Important only for Win 9x systems */ - - if (!wincap.supports_reading_modem_output_lines ()) - { - if (EscapeCommFunction (get_handle (), SETDTR) == 0) - system_printf ("couldn't set initial state of DTR for %s, %E", get_name ()); - if (EscapeCommFunction (get_handle (), SETRTS) == 0) - system_printf ("couldn't set initial state of RTS for %s, %E", get_name ()); - - /* even though one of above functions fail I have to set rts and dtr - variables to initial value. */ - rts = TIOCM_RTS; - dtr = TIOCM_DTR; - } - - SetCommMask (get_handle (), EV_RXCHAR); - set_open_status (); - 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 = 300000; - - 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; -} - - -/* ioctl: */ -int -fhandler_serial::ioctl (unsigned int cmd, void *buffer) -{ - - DWORD ev; - COMSTAT st; - DWORD action; - DWORD modemLines; - DWORD mcr; - DWORD cbReturned; - bool result; - int modemStatus; - int request; - - request = *(int *) buffer; - action = 0; - modemStatus = 0; - if (!ClearCommError (get_handle (), &ev, &st)) - return -1; - switch (cmd) - { - case TIOCMGET: - if (GetCommModemStatus (get_handle (), &modemLines) == 0) - return -1; - if (modemLines & MS_CTS_ON) - modemStatus |= TIOCM_CTS; - if (modemLines & MS_DSR_ON) - modemStatus |= TIOCM_DSR; - if (modemLines & MS_RING_ON) - modemStatus |= TIOCM_RI; - if (modemLines & MS_RLSD_ON) - modemStatus |= TIOCM_CD; - if (!wincap.supports_reading_modem_output_lines ()) - modemStatus |= rts | dtr; - else - { - result = DeviceIoControl (get_handle (), - 0x001B0078, - NULL, 0, &mcr, 4, &cbReturned, 0); - if (!result) - return -1; - if (cbReturned != 4) - return -1; - if (mcr & 2) - modemStatus |= TIOCM_RTS; - if (mcr & 1) - modemStatus |= TIOCM_DTR; - } - *(int *) buffer = modemStatus; - return 0; - case TIOCMSET: - if (request & TIOCM_RTS) - { - if (EscapeCommFunction (get_handle (), SETRTS) == 0) - return -1; - else - rts = TIOCM_RTS; - } - else - { - if (EscapeCommFunction (get_handle (), CLRRTS) == 0) - return -1; - else - rts = 0; - } - if (request & TIOCM_DTR) - { - if (EscapeCommFunction (get_handle (), SETDTR) == 0) - return -1; - else - dtr = TIOCM_DTR; - } - else - { - if (EscapeCommFunction (get_handle (), CLRDTR) == 0) - return -1; - else - dtr = 0; - } - return 0; - case TIOCINQ: - if (ev & CE_FRAME | ev & CE_IOE | ev & CE_OVERRUN | - ev & CE_RXOVER | ev & CE_RXPARITY) - return -1; - *(int *) buffer = st.cbInQue; - return 0; - default: - return -1; - } -} - -/* 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--) - { - 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_; - 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_ = 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); -} - -void -fhandler_serial::fixup_after_exec (HANDLE) -{ - overlapped_setup (); - debug_printf ("io_status.hEvent %p", io_status.hEvent); - return; -} - -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); -} |