36#if _WIN32 || _POSIX_C_SOURCE >= 200112L
38static int serial_flush(
struct io_handle *handle);
39static 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;
177error_SetCommTimeouts:
179error_GetCommTimeouts:
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;
This is the internal header file of the default implementation of the I/O device handle methods.
@ ERRNUM_BADF
Bad file descriptor.
@ ERRNUM_NOTTY
Inappropriate I/O control operation.
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
struct io_handle * io_handle_alloc(const struct io_handle_vtab *vtab)
Allocates a new I/O device handle from a virtual table.
@ IO_TYPE_SERIAL
A serial I/O device.
io_handle_t io_handle_acquire(io_handle_t handle)
Increments the reference count of an I/O device handle.
#define IO_HANDLE_ERROR
The value of an invalid I/O device handle.
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.
io_handle_t io_open_serial(const char *path, io_attr_t *attr)
Opens a serial I/O device.
int io_purge(io_handle_t handle, int flags)
Purges the receive and/or transmit buffers of a serial I/O device.
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 header file is part of the I/O library; it contains the serial I/O declarations.
@ IO_PURGE_TX
Purge the transmit buffer of a serial I/O device.
@ IO_PURGE_RX
Purge the receive buffer of a serial I/O device.
This is the internal header file of the Windows-specific I/O declarations.
This is the internal header file of the serial I/O attributes declarations.
This header file is part of the C11 and POSIX compatibility library; it includes <string....
The virtual table of an I/O device handle.
int(* purge)(struct io_handle *handle, int flags)
A pointer to the purge method.
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...
int fd
The native file descriptor.
int flags
The I/O device flags (any combination of IO_FLAG_NO_CLOSE and IO_FLAG_NONBLOCK).
const struct io_handle_vtab * vtab
A pointer to the virtual table.
An opaque serial I/O device attributes type.