unsafe void UpdateSettings() { lock (_lock) { int ret; int handle = _handle; if (handle >= 0) { if (_settingsChanged) { int baudRate = _ser.BaudRate; int dataBits = _ser.DataBits; var parity = _ser.Parity; int stopBits = _ser.StopBits; ret = NativeMethods.retry(() => NativeMethods.cfsetspeed(ref _newSettings, (UIntPtr)Math.Max(1, baudRate))); if (ret < 0) { throw new IOException("cfsetspeed failed."); } ulong cflag = (ulong)_newSettings.c_cflag; // data bits cflag &= ~NativeMethods.CSIZE; if (dataBits == 7) { cflag |= NativeMethods.CS7; } else { cflag |= NativeMethods.CS8; } // parity bits cflag &= ~NativeMethods.PARENB & ~NativeMethods.PARODD; if (parity == SerialParity.Even) { cflag |= NativeMethods.PARENB; } else if (parity == SerialParity.Odd) { cflag |= NativeMethods.PARENB | NativeMethods.PARODD; } // stop bits cflag &= ~NativeMethods.CSTOPB; if (stopBits == 2) { cflag |= NativeMethods.CSTOPB; } _newSettings.c_cflag = (UIntPtr)cflag; ret = NativeMethods.retry(() => NativeMethods.tcsetattr(handle, NativeMethods.TCSANOW, ref _newSettings)); if (ret < 0) { throw new IOException("tcsetattr failed."); } ret = NativeMethods.retry(() => NativeMethods.tcflush(handle, NativeMethods.TCIFLUSH)); if (ret < 0) { throw new IOException("tcflush failed."); } _settingsChanged = false; } } } }