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);
206 return handle->
vtab->
purge(handle, flags);
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;
300 return tcflush(handle->
fd, (flags & IO_PURGE_RX)
301 ? (flags & IO_PURGE_TX) ? TCIOFLUSH : TCIFLUSH
302 : (flags & IO_PURGE_TX) ? TCOFLUSH : 0);
307 #endif // _WIN32 || _POSIX_C_SOURCE >= 200112L Inappropriate I/O control operation.
This header file is part of the C11 and POSIX compatibility library; it includes <string.h> and defines any missing functionality.
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
This is the internal header file of the serial I/O attributes declarations.
This is the internal header file of the default implementation of the I/O device handle methods...
int type
The type of the device (one of IO_TYPE_CAN, IO_TYPE_FILE, IO_TYPE_PIPE, IO_TYPE_SERIAL or IO_TYPE_SOC...
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
io_handle_t io_handle_acquire(io_handle_t handle)
Increments the reference count of an I/O device handle.
int io_purge(io_handle_t handle, int flags)
Purges the receive and/or transmit buffers of a serial I/O device.
Purge the transmit buffer of a serial I/O device.
io_handle_t io_open_serial(const char *path, io_attr_t *attr)
Opens a serial I/O device.
An opaque serial I/O device attributes type.
#define IO_HANDLE_ERROR
The value of an invalid I/O device handle.
const struct io_handle_vtab * vtab
A pointer to the virtual table.
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function...
The virtual table of an I/O device handle.
This header file is part of the I/O library; it contains the serial I/O declarations.
int(* purge)(struct io_handle *handle, int flags)
A pointer to the purge method.
int io_serial_get_attr(io_handle_t handle, io_attr_t *attr)
Retrieves the current attributes of a serial I/O device and stores them in *attr. ...
This is the internal header file of the I/O library.
int flags
The I/O device flags (any combination of IO_FLAG_NO_CLOSE and IO_FLAG_NONBLOCK).
int io_serial_set_attr(io_handle_t handle, const io_attr_t *attr)
Sets the attributes of a serial I/O device to those in *attr.
int fd
The native file descriptor.
struct io_handle * io_handle_alloc(const struct io_handle_vtab *vtab)
Allocates a new I/O device handle from a virtual table.
Purge the receive buffer of a serial I/O device.