32 #if defined(_WIN32) || _POSIX_C_SOURCE >= 200112L
34 static int serial_flush(
struct io_handle *handle);
35 static int serial_purge(
struct io_handle *handle,
int flags);
39 .fini = &default_fini,
40 .flags = &default_flags,
41 .read = &default_read,
42 .write = &default_write,
43 .flush = &serial_flush,
44 .purge = &serial_purge };
54 HANDLE
fd = CreateFileA(path, GENERIC_READ | GENERIC_WRITE, 0, NULL,
55 OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
56 if (
fd == INVALID_HANDLE_VALUE) {
58 goto error_CreateFile;
61 if (!SetCommMask(
fd, EV_RXCHAR)) {
63 goto error_SetCommMask;
67 memset(&DCB, 0,
sizeof(DCB));
68 DCB.DCBlength =
sizeof(DCB);
69 if (!GetCommState(
fd, &DCB)) {
71 goto error_GetCommState;
74 COMMTIMEOUTS CommTimeouts;
75 if (!GetCommTimeouts(
fd, &CommTimeouts)) {
77 goto error_GetCommTimeouts;
81 *io_attr_lpDCB(attr) = DCB;
82 *io_attr_lpCommTimeouts(attr) = CommTimeouts;
87 DCB.fOutxCtsFlow = FALSE;
88 DCB.fOutxDsrFlow = FALSE;
89 DCB.fDtrControl = DTR_CONTROL_ENABLE;
90 DCB.fDsrSensitivity = FALSE;
91 DCB.fTXContinueOnXoff = TRUE;
94 DCB.fErrorChar = FALSE;
96 DCB.fRtsControl = RTS_CONTROL_ENABLE;
97 DCB.fAbortOnError = TRUE;
99 DCB.Parity = NOPARITY;
101 if (!SetCommState(
fd, &DCB)) {
103 goto error_SetCommState;
109 CommTimeouts.ReadIntervalTimeout = MAXDWORD;
110 CommTimeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
111 CommTimeouts.ReadTotalTimeoutConstant = MAXDWORD - 1;
113 CommTimeouts.WriteTotalTimeoutMultiplier = 0;
114 CommTimeouts.WriteTotalTimeoutConstant = 0;
116 if (!SetCommTimeouts(
fd, &CommTimeouts)) {
118 goto error_SetCommTimeouts;
125 fd = open(path, O_RDWR | O_NOCTTY | O_CLOEXEC);
126 }
while (
fd == -1 && errno == EINTR);
133 if (tcgetattr(fd, &ios) == -1) {
135 goto error_tcgetattr;
139 *(
struct termios *)attr = ios;
142 ios.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR | ISTRIP | IXON
144 ios.c_oflag &= ~OPOST;
145 ios.c_cflag &= ~(CSIZE | PARENB);
147 ios.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
149 ios.c_iflag |= IGNPAR;
150 ios.c_cflag |= CREAD | CLOCAL;
155 if (tcsetattr(fd, TCSANOW, &ios) == -1) {
157 goto error_tcsetattr;
164 goto error_alloc_handle;
173 error_SetCommTimeouts:
175 error_GetCommTimeouts:
190 #endif // _WIN32 || _POSIX_C_SOURCE >= 200112L
200 assert(handle->
vtab);
209 #if defined(_WIN32) || _POSIX_C_SOURCE >= 200112L
222 LPDCB lpDCB = io_attr_lpDCB(attr);
223 memset(lpDCB, 0,
sizeof(*lpDCB));
224 lpDCB->DCBlength =
sizeof(*lpDCB);
225 if (!GetCommState(handle->
fd, lpDCB))
229 return GetCommTimeouts(handle->
fd, io_attr_lpCommTimeouts(attr))
233 return tcgetattr(handle->
fd, (
struct termios *)attr);
248 if (!SetCommState(handle->
fd, io_attr_lpDCB(attr)))
251 if (!SetCommTimeouts(handle->
fd, io_attr_lpCommTimeouts(attr)))
260 result = tcsetattr(handle->
fd, TCSANOW,
261 (
const struct termios *)attr);
262 }
while (result == -1 && errno == EINTR);
273 return FlushFileBuffers(handle->
fd) ? 0 : -1;
279 result = tcdrain(handle->
fd);
280 }
while (result == -1 && errno == EINTR);
293 dwFlags |= PURGE_RXABORT | PURGE_RXCLEAR;
295 dwFlags |= PURGE_TXABORT | PURGE_TXCLEAR;
297 return PurgeComm(handle->
fd, dwFlags) ? 0 : -1;
307 #endif // _WIN32 || _POSIX_C_SOURCE >= 200112L