36 #if _WIN32 || _POSIX_C_SOURCE >= 200112L
38 static int serial_flush(
struct io_handle *handle);
39 static int serial_purge(
struct io_handle *handle,
int flags);
43 .fini = &default_fini,
44 .flags = &default_flags,
45 .read = &default_read,
46 .write = &default_write,
47 .flush = &serial_flush,
48 .purge = &serial_purge };
58 HANDLE
fd = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
59 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
60 if (
fd == INVALID_HANDLE_VALUE) {
62 goto error_CreateFile;
65 if (!SetCommMask(
fd, EV_RXCHAR)) {
67 goto error_SetCommMask;
71 memset(&DCB, 0,
sizeof(DCB));
72 DCB.DCBlength =
sizeof(DCB);
73 if (!GetCommState(
fd, &DCB)) {
75 goto error_GetCommState;
78 COMMTIMEOUTS CommTimeouts;
79 if (!GetCommTimeouts(
fd, &CommTimeouts)) {
81 goto error_GetCommTimeouts;
85 *io_attr_lpDCB(attr) = DCB;
86 *io_attr_lpCommTimeouts(attr) = CommTimeouts;
91 DCB.fOutxCtsFlow = FALSE;
92 DCB.fOutxDsrFlow = FALSE;
93 DCB.fDtrControl = DTR_CONTROL_ENABLE;
94 DCB.fDsrSensitivity = FALSE;
95 DCB.fTXContinueOnXoff = TRUE;
98 DCB.fErrorChar = FALSE;
100 DCB.fRtsControl = RTS_CONTROL_ENABLE;
101 DCB.fAbortOnError = TRUE;
103 DCB.Parity = NOPARITY;
105 if (!SetCommState(
fd, &DCB)) {
107 goto error_SetCommState;
113 CommTimeouts.ReadIntervalTimeout = MAXDWORD;
114 CommTimeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
115 CommTimeouts.ReadTotalTimeoutConstant = MAXDWORD - 1;
117 CommTimeouts.WriteTotalTimeoutMultiplier = 0;
118 CommTimeouts.WriteTotalTimeoutConstant = 0;
120 if (!SetCommTimeouts(
fd, &CommTimeouts)) {
122 goto error_SetCommTimeouts;
129 fd = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC);
130 }
while (
fd == -1 && errno == EINTR);
137 if (tcgetattr(fd, &ios) == -1) {
139 goto error_tcgetattr;
143 *(
struct termios *)attr = ios;
146 ios.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR | ISTRIP | IXON
148 ios.c_oflag &= ~OPOST;
149 ios.c_cflag &= ~(CSIZE | PARENB);
151 ios.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
153 ios.c_iflag |= IGNPAR;
154 ios.c_cflag |= CREAD | CLOCAL;
159 if (tcsetattr(fd, TCSANOW, &ios) == -1) {
161 goto error_tcsetattr;
168 goto error_alloc_handle;
177 error_SetCommTimeouts:
179 error_GetCommTimeouts:
194 #endif // _WIN32 || _POSIX_C_SOURCE >= 200112L
204 assert(handle->
vtab);
213 #if _WIN32 || _POSIX_C_SOURCE >= 200112L
226 LPDCB lpDCB = io_attr_lpDCB(attr);
227 memset(lpDCB, 0,
sizeof(*lpDCB));
228 lpDCB->DCBlength =
sizeof(*lpDCB);
229 if (!GetCommState(handle->
fd, lpDCB))
233 return GetCommTimeouts(handle->
fd, io_attr_lpCommTimeouts(attr))
237 return tcgetattr(handle->
fd, (
struct termios *)attr);
252 if (!SetCommState(handle->
fd, io_attr_lpDCB(attr)))
255 if (!SetCommTimeouts(handle->
fd, io_attr_lpCommTimeouts(attr)))
264 result = tcsetattr(handle->
fd, TCSANOW,
265 (
const struct termios *)attr);
266 }
while (result == -1 && errno == EINTR);
277 return FlushFileBuffers(handle->
fd) ? 0 : -1;
283 result = tcdrain(handle->
fd);
284 }
while (result == -1 && errno == EINTR);
297 dwFlags |= PURGE_RXABORT | PURGE_RXCLEAR;
299 dwFlags |= PURGE_TXABORT | PURGE_TXCLEAR;
301 return PurgeComm(handle->
fd, dwFlags) ? 0 : -1;
311 #endif // _WIN32 || _POSIX_C_SOURCE >= 200112L
313 #endif // !LELY_NO_STDIO