VirtualBox

Ignore:
Timestamp:
Jan 18, 2018 3:21:10 PM (7 years ago)
Author:
vboxsync
Message:

Runtime/r3/serialport-posix: Fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/serialport-posix.cpp

    r69986 r70633  
    218218    cfsetispeed(&pThis->PortCfg, B9600);
    219219    cfsetospeed(&pThis->PortCfg, B9600);
    220     pThis->PortCfg.c_cflag = CS8 | CLOCAL; /* 8 data bits, ignore modem control lines. */
     220    pThis->PortCfg.c_cflag |= CS8 | CLOCAL; /* 8 data bits, ignore modem control lines. */
    221221    if (pThis->fOpenFlags & RTSERIALPORT_OPEN_F_READ)
    222222        pThis->PortCfg.c_cflag |= CREAD;   /* Enable receiver. */
     
    270270 *
    271271 * @returns IPRT status code.
     272 * @param   pThis                   The internal serial port instance data.
    272273 * @param   pCfg                    Pointer to the serial port config descriptor.
    273274 * @param   pTermios                Pointer to the termios structure to fill.
    274275 * @param   pErrInfo                Additional error to be set when the conversion fails.
    275276 */
    276 static int rtSerialPortCfg2Termios(PCRTSERIALPORTCFG pCfg, struct termios *pTermios, PRTERRINFO pErrInfo)
     277static int rtSerialPortCfg2Termios(PRTSERIALPORTINTERNAL pThis, PCRTSERIALPORTCFG pCfg, struct termios *pTermios, PRTERRINFO pErrInfo)
    277278{
    278279    RT_NOREF(pErrInfo); /** @todo Make use of the error info. */
     
    351352
    352353        /* Assign new flags. */
     354        if (pThis->fOpenFlags & RTSERIALPORT_OPEN_F_READ)
     355            pTermios->c_cflag |= CREAD;   /* Enable receiver. */
    353356        pTermios->c_cflag = (pTermios->c_cflag & ~fCFlagMask) | fCFlagNew;
     357        pTermios->c_lflag &= ~(ICANON | ECHO | ECHOE | ECHONL | ECHOK | ISIG | IEXTEN);
     358        pTermios->c_iflag = INPCK; /* Input parity checking. */
     359        pTermios->c_cc[VMIN]  = 0; /* Achieve non-blocking behavior. */
     360        pTermios->c_cc[VTIME] = 0;
     361        cfsetispeed(pTermios, enmSpeed);
     362        cfsetospeed(pTermios, enmSpeed);
    354363    }
    355364    else
     
    637646    if (pThis)
    638647    {
    639         int fPsxFlags = O_NOCTTY;
     648        int fPsxFlags = O_NOCTTY | O_NONBLOCK;
    640649
    641650        if ((fFlags & RTSERIALPORT_OPEN_F_READ) && !(fFlags & RTSERIALPORT_OPEN_F_WRITE))
     
    824833
    825834    struct termios PortCfgNew; RT_ZERO(PortCfgNew);
    826     int rc = rtSerialPortCfg2Termios(pCfg, &PortCfgNew, pErrInfo);
     835    int rc = rtSerialPortCfg2Termios(pThis, pCfg, &PortCfgNew, pErrInfo);
    827836    if (RT_SUCCESS(rc))
    828837    {
    829         int rcPsx = tcsetattr(pThis->iFd, TCSANOW, &PortCfgNew);
    830         if (rcPsx == -1)
     838        int rcPsx = tcflush(pThis->iFd, TCIOFLUSH);
     839        if (!rcPsx)
     840        {
     841            rcPsx = tcsetattr(pThis->iFd, TCSANOW, &PortCfgNew);
     842            if (rcPsx == -1)
     843                rc = RTErrConvertFromErrno(errno);
     844            else
     845                memcpy(&pThis->PortCfg, &PortCfgNew, sizeof(struct termios));
     846
     847#ifdef RT_OS_LINUX
     848            /*
     849             * XXX In Linux, if a thread calls tcsetattr while the monitor thread is
     850             * waiting in ioctl for a modem status change then 8250.c wrongly disables
     851             * modem irqs and so the monitor thread never gets released. The workaround
     852             * is to send a signal after each tcsetattr.
     853             */
     854            if (pThis->fOpenFlags & RTSERIALPORT_OPEN_F_SUPPORT_STATUS_LINE_MONITORING)
     855                RTThreadPoke(pThis->hMonThrd);
     856#endif
     857        }
     858        else
    831859            rc = RTErrConvertFromErrno(errno);
    832         else
    833             memcpy(&pThis->PortCfg, &PortCfgNew, sizeof(struct termios));
    834 
    835 #ifdef RT_OS_LINUX
    836         /*
    837          * XXX In Linux, if a thread calls tcsetattr while the monitor thread is
    838          * waiting in ioctl for a modem status change then 8250.c wrongly disables
    839          * modem irqs and so the monitor thread never gets released. The workaround
    840          * is to send a signal after each tcsetattr.
    841          */
    842         if (pThis->fOpenFlags & RTSERIALPORT_OPEN_F_SUPPORT_STATUS_LINE_MONITORING)
    843             RTThreadPoke(pThis->hMonThrd);
    844 #endif
    845860    }
    846861
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette