aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libtio/cdefs.h3
-rw-r--r--include/libtio/io/serial.h4
-rw-r--r--include/libtio/native.h2
-rw-r--r--lib/serial/builtin/unix_dev.c7
-rw-r--r--lib/serial/list.c8
-rw-r--r--lib/stream/builtin/unix.c271
6 files changed, 174 insertions, 121 deletions
diff --git a/include/libtio/cdefs.h b/include/libtio/cdefs.h
index b896fa7..416fea9 100644
--- a/include/libtio/cdefs.h
+++ b/include/libtio/cdefs.h
@@ -16,9 +16,6 @@
#ifndef LIBTIO_CDEFS_H
# define LIBTIO_CDEFS_H 20180710
# include "config.h"
-
-# define _POSIX_C_SOURCE 200809L
-
# include <stddef.h>
# include <time.h>
diff --git a/include/libtio/io/serial.h b/include/libtio/io/serial.h
index 12242f2..f659ae8 100644
--- a/include/libtio/io/serial.h
+++ b/include/libtio/io/serial.h
@@ -102,10 +102,12 @@ struct tio_serial_attrs {
# define TIO_DTRDIS 0x0000
# define TIO_DTRENB 0x0008
# define TIO_DTRHAND 0x0018
+# define TIO_DTRNOHAND 0x0000
# define TIO_RTSDIS 0x0000
# define TIO_RTSENB 0x0020
# define TIO_RTSHAND 0x0060
+# define TIO_RTSNOHAND 0x0000
/* The XON/XOFF software control settings.
*
@@ -160,6 +162,8 @@ struct tio_serial_attrs {
# define TIO_SERIALFLAG_XINOUT 6
# define TIO_SERIALFLAG_XOUTIN 6
+# define TIO_SERIALFLAG_DTRRTS 96
+# define TIO_SERIALFLAG_RTSDTR 96
# define TIO_SERIALFLAG_ALL 127
/* ---
diff --git a/include/libtio/native.h b/include/libtio/native.h
index f5600bc..eaffb01 100644
--- a/include/libtio/native.h
+++ b/include/libtio/native.h
@@ -21,7 +21,7 @@ TIO_BEGIN_DECLS
* - `LIBTIO_DISABLED_WINDOWS`: disable Windows API support.
* - `LIBTIO_DISABLED_MACOS`: disable MacOS (OS X) support. */
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L
+# if defined(__unix__) && __unix__
# else
# define LIBTIO_DISABLED_UNIX 1
# endif
diff --git a/lib/serial/builtin/unix_dev.c b/lib/serial/builtin/unix_dev.c
index 037f425..e165e22 100644
--- a/lib/serial/builtin/unix_dev.c
+++ b/lib/serial/builtin/unix_dev.c
@@ -1,6 +1,7 @@
#include "../../internals.h"
#ifndef LIBTIO_DISABLED_UNIX
+# include <errno.h>
# include <string.h>
# include <dirent.h>
# include <unistd.h>
@@ -81,7 +82,7 @@ TIO_HOOK(int) next_serial_port(cookie_t *cookie, char const **ptr)
/* Get the next entry. */
if (!(dr = readdir(cookie->dp)))
- return (casio_error_iter);
+ return (tio_error_iter);
/* Check the name. */
@@ -103,7 +104,7 @@ TIO_HOOK(int) next_serial_port(cookie_t *cookie, char const **ptr)
TIO_HOOK(void) end_iter(cookie_t *cookie)
{
- closedir(d);
+ closedir(cookie->dp);
tio_free(cookie);
}
@@ -130,7 +131,7 @@ TIO_EXTERN(int) tio_list_unix_serial_ports_using_cu_devices(tio_iter_t **iterp)
/* Create the cookie. */
if (!(cookie = tio_alloc(1, sizeof(cookie) + path_max)))
- return (casio_error_alloc);
+ return (tio_error_alloc);
cookie->path = (char *)(void *)&cookie[1];
diff --git a/lib/serial/list.c b/lib/serial/list.c
index 8b94114..9f86bac 100644
--- a/lib/serial/list.c
+++ b/lib/serial/list.c
@@ -4,10 +4,10 @@
* `spl_last_successful_candidate`: last candidate which returned
* a valid iterator. */
-typedef TIO_EXTERN_TYPE(int) (*spl_func)
+typedef TIO_EXTERN_TYPE(int) spl_func
OF((tio_iter_t **));
-TIO_LOCAL_DATA(spl_func const * const) spl_candidates[] = {
+TIO_LOCAL_DATA(spl_func *) spl_candidates[] = {
#ifndef LIBTIO_DISABLED_WINDOWS
&tio_list_windows_serial_ports,
#endif
@@ -20,7 +20,7 @@ TIO_LOCAL_DATA(spl_func const * const) spl_candidates[] = {
NULL
};
-TIO_LOCAL_DATA(spl_func const *) spl_last_successful_candidate = 0;
+TIO_LOCAL_DATA(spl_func *) spl_last_successful_candidate = 0;
/* `tio_list_serial_ports()`: list the serial ports, in an agnostic way. */
@@ -35,7 +35,7 @@ TIO_EXTERN(int) tio_list_serial_ports(tio_iter_t **iterp)
}
{
- spl_func const * const *func;
+ spl_func **func;
for (func = spl_candidates; func; func++) {
err = (**func)(iterp);
diff --git a/lib/stream/builtin/unix.c b/lib/stream/builtin/unix.c
index 6ea5309..d625a35 100644
--- a/lib/stream/builtin/unix.c
+++ b/lib/stream/builtin/unix.c
@@ -14,6 +14,10 @@
attrs->tio_serial_attrs_flags &= ~(MASK); \
attrs->tio_serial_attrs_flags |= (VALUE); \
}
+# define SET_CHAR(CAR, VALUE) \
+ { \
+ attrs->tio_serial_attrs_cc[(CAR)] = (VALUE); \
+ }
TIO_LOCAL(int) unix_get_attrs(tio_serial_attrs_t *attrs, int fd)
{
@@ -55,6 +59,11 @@ TIO_LOCAL(int) unix_get_attrs(tio_serial_attrs_t *attrs, int fd)
SET_MASK(TIO_XINMASK, term.c_iflag & IXON ? TIO_XINENB : TIO_XINDIS)
SET_MASK(TIO_XOUTMASK, term.c_iflag & IXOFF ? TIO_XOUTENB : TIO_XOUTDIS)
+ /* Characters. */
+
+ SET_CHAR(TIO_XON, term.c_cc[VSTART])
+ SET_CHAR(TIO_XOFF, term.c_cc[VSTOP])
+
/* Get DTR/RTS status. */
if (ioctl(fd, TIOCMGET, &status) >= 0)
@@ -82,13 +91,14 @@ struct cookie {
/* File descriptor, a boolean to know if we ought to close the
* file descriptor at stream closing, and the timeout. */
- int _fd, _cl;
- unsigned int _to;
+ int fd, cl;
+ unsigned int to;
/* Buffer [control] */
- ssize_t _str, _end;
- unsigned char _buf[BUFSIZE];
+ ssize_t str;
+ ssize_t end;
+ unsigned char buf[BUFSIZE];
};
/* `unix_read()`: read from a UNIX stream. */
@@ -96,19 +106,19 @@ struct cookie {
TIO_HOOK(int) unix_read(cookie_t *cookie, unsigned char *dest,
size_t size)
{
- int fd = cookie->_fd;
+ int fd = cookie->fd;
/* Transmit what's already in the buffer. */
- if (cookie->_str <= cookie->_end) {
+ if (cookie->str <= cookie->end) {
size_t tocopy;
- tocopy = cookie->_end - cookie->_start + 1;
+ tocopy = cookie->end - cookie->str + 1;
if (tocopy > size)
tocopy = size;
- memcpy(dest, &cookie->_buf[cookie->_start], tocopy);
- cookie->_str += tocopy;
+ memcpy(dest, &cookie->buf[cookie->str], tocopy);
+ cookie->str += tocopy;
dest += tocopy;
size -= tocopy;
@@ -124,7 +134,7 @@ TIO_HOOK(int) unix_read(cookie_t *cookie, unsigned char *dest,
/* Receive. */
- recv = read(fd, cookie->_buf, BUFSIZE);
+ recv = read(fd, cookie->buf, BUFSIZE);
if (!recv)
continue;
@@ -148,14 +158,14 @@ TIO_HOOK(int) unix_read(cookie_t *cookie, unsigned char *dest,
/* Copy to destination. */
- memcpy(dest, cookie->_buf, tocopy);
+ memcpy(dest, cookie->buf, tocopy);
dest += tocopy;
size -= tocopy;
/* Correct start and end points. */
- cookie->_str = tocopy;
- cookie->_end = (size_t)recv - 1;
+ cookie->str = tocopy;
+ cookie->end = (size_t)recv - 1;
}
return (tio_error_ok);
@@ -166,7 +176,7 @@ TIO_HOOK(int) unix_read(cookie_t *cookie, unsigned char *dest,
TIO_HOOK(int) unix_write(cookie_t *cookie,
unsigned char const *data, size_t size)
{
- int fd = cookie->_fd;
+ int fd = cookie->fd;
/* Send. */
@@ -198,14 +208,14 @@ TIO_HOOK(int) unix_write(cookie_t *cookie,
TIO_HOOK(int) unix_seek(cookie_t *cookie, tio_off_t *offp,
tio_whence_t whence)
{
- int fd = cookie->_fd;
+ int fd = cookie->fd;
off_t off;
int wh;
/* Check parameters. */
if (offp == NULL)
- return (tio_error_invalid);
+ return (tio_error_arg);
off = (off_t)*offp;
switch (whence) {
@@ -221,12 +231,12 @@ TIO_HOOK(int) unix_seek(cookie_t *cookie, tio_off_t *offp,
# endif
default:
- return (tio_error_invalid);
+ return (tio_error_arg);
}
/* Do the seek. */
- if (lseek(fd, (off_t)*off, wh) == (off_t)-1) switch (errno) {
+ if (lseek(fd, (off_t)*offp, wh) == (off_t)-1) switch (errno) {
default:
msg((ll_error, "errno was %d: %s", errno, strerror(errno)));
break;
@@ -243,88 +253,137 @@ TIO_HOOK(int) unix_seek(cookie_t *cookie, tio_off_t *offp,
# define SPEED(TIO, NATIVE) case TIO: speed = NATIVE; break;
TIO_HOOK(int) unix_set_attrs(cookie_t *cookie,
- tio_serial_attrs_t const *settings)
+ tio_serial_attrs_t const *settings, unsigned long flags)
{
- struct termios term;
- unsigned int status, dtrflags, rtsflags;
- int fd = cookie->_fd;
- speed_t speed;
+ int fd = cookie->fd;
- /* Get the speed. */
+ if (flags & (TIO_SERIALFLAG_SPEED | TIO_SERIALFLAG_XINOUT
+ | TIO_SERIALFLAG_STOP | TIO_SERIALFLAG_PARITY)) {
+ struct termios term;
+ speed_t speed;
+
+ /* Get the speed. */
+
+ if (flags & TIO_SERIALFLAG_SPEED) {
+ switch (settings->tio_serial_attrs_speed) {
+ SPEED(TIO_B1200, B1200)
+ SPEED(TIO_B2400, B2400)
+ SPEED(TIO_B4800, B4800)
+ SPEED(TIO_B9600, B9600)
+ SPEED(TIO_B19200, B19200)
+ SPEED(TIO_B38400, B38400)
+ SPEED(TIO_B57600, B57600)
+ SPEED(TIO_B115200, B115200)
+
+ default:
+ msg((ll_error, "Speed was unsupported by termios: %u",
+ settings->tio_serial_attrs_speed));
+ return (tio_error_op);
+ }
+ }
- switch (settings->tio_serial_attrs_speed) {
- SPEED(TIO_B1200, B1200)
- SPEED(TIO_B2400, B2400)
- SPEED(TIO_B4800, B4800)
- SPEED(TIO_B9600, B9600)
- SPEED(TIO_B19200, B19200)
- SPEED(TIO_B38400, B38400)
- SPEED(TIO_B57600, B57600)
- SPEED(TIO_B115200, B115200)
+ /* Get the current configuration. */
- default:
- msg((ll_error, "Speed was unsupported by termios: %u",
- settings->tio_serial_attrs_speed));
- return (tio_error_op);
- }
+ if (tcgetattr(fd, &term) < 0)
+ return (tio_error_unknown);
- /* Get the current configuration. */
+ /* Set the speed. */
- if (tcgetattr(fd, &term) < 0)
- return (tio_error_unknown);
+ if (flags & TIO_SERIALFLAG_SPEED) {
+ cfsetispeed(&term, speed);
+ cfsetospeed(&term, speed);
+ }
+
+ /* Input flags. */
- /* Set the speed. */
+ term.c_iflag &= ~(IGNBRK | IGNCR | BRKINT | PARMRK | ISTRIP | INLCR
+ | ICRNL | IGNPAR);
+ if (flags & TIO_SERIALFLAG_XIN) {
+ term.c_iflag &= ~IXON;
- cfsetispeed(&term, speed);
- cfsetospeed(&term, speed);
+ if ((settings->tio_serial_attrs_flags & TIO_XINMASK)
+ == TIO_XINENB)
+ term.c_iflag &= ~IXON;
+ }
- /* Input flags. */
+ if (flags & TIO_SERIALFLAG_XOUT) {
+ term.c_iflag &= ~IXOFF;
- term.c_iflag &= ~(IGNBRK | IGNCR | BRKINT | PARMRK | ISTRIP | INLCR
- | ICRNL | IGNPAR | IXON | IXOFF);
- if (settings->tio_serial_attrs_flags & TIO_XONMASK)
- term.c_iflag |= IXON;
- if (settings->tio_serial_attrs_flags & TIO_XOFFMASK)
- term.c_iflag |= IXOFF;
+ if ((settings->tio_serial_attrs_flags & TIO_XOUTMASK)
+ == TIO_XOUTENB)
+ term.c_iflag |= IXOFF;
+ }
- /* Output flags, local modes. */
+ /* Output flags, local modes. */
- term.c_oflag = 0;
- term.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+ term.c_oflag = 0;
+ term.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
- /* Control flags. */
+ /* Control flags. */
- term.c_cflag &= ~(PARENB | PARODD | CREAD | CSTOPB | CSIZE);
- term.c_cflag |= CREAD | CS8;
- if (settings->tio_serial_attrs_flags & TIO_STOTWO)
- term.c_cflag |= CSTOPB;
- if (settings->tio_serial_attrs_flags & TIO_PARENB)
- term.c_cflag |= PARENB;
- if (settings->tio_serial_attrs_flags & TIO_PARODD)
- term.c_cflag |= PARODD;
+ term.c_cflag &= ~(CREAD | CSIZE);
+ term.c_cflag |= CREAD | CS8;
- /* Update the termios settings! */
+ if (flags & TIO_SERIALFLAG_STOP) {
+ term.c_cflag &= ~CSTOPB;
- if (tcsetattr(fd, TCSANOW, &term))
- return (tio_error_unknown);
+ if (settings->tio_serial_attrs_flags & TIO_STOTWO)
+ term.c_cflag |= CSTOPB;
+ }
- /* Get line status. */
+ if (flags & TIO_SERIALFLAG_PARITY) {
+ term.c_cflag &= ~(PARENB | PARODD);
- if (ioctl(fd, TIOCMGET, &status) >= 0)
- status = 0;
- status &= ~(TIOCM_DTR | TIOCM_RTS);
-
- /* Activate DTR and RTS.
- * TODO: use the 'X' versions if available? */
-
- dtrflags = settings->tio_serial_attrs_flags & TIO_DTRMASK;
- rtsflags = settings->tio_serial_attrs_flags & TIO_RTSMASK;
- if (dtrflags & TIO_DTRENB)
- status |= TIOCM_DTR;
- if (rtsflags & TIO_RTSENB)
- status |= TIOCM_RTS;
- if (ioctl(fd, TIOCMSET, &status) < 0)
- return (tio_error_unknown);
+ if (settings->tio_serial_attrs_flags & TIO_PARENB) {
+ term.c_cflag |= PARENB;
+
+ if (settings->tio_serial_attrs_flags & TIO_PARODD)
+ term.c_cflag |= PARODD;
+ }
+ }
+
+ /* Update the termios settings! */
+
+ if (tcsetattr(fd, TCSANOW, &term))
+ return (tio_error_unknown);
+ }
+
+ if (flags & TIO_SERIALFLAG_DTRRTS) {
+ unsigned int status;
+
+ /* Get line status. */
+
+ if (ioctl(fd, TIOCMGET, &status) >= 0)
+ status = 0;
+
+ /* Enable DTR and RTS.
+ * TODO: use the 'X' versions if available? */
+
+ if (flags & TIO_SERIALFLAG_DTR) {
+ status &= ~TIOCM_DTR;
+
+ switch (settings->tio_serial_attrs_flags & TIO_DTRMASK) {
+ case TIO_DTRENB | TIO_DTRHAND:
+ case TIO_DTRENB | TIO_DTRNOHAND:
+ status |= TIOCM_DTR;
+ break;
+ }
+ }
+
+ if (flags & TIO_SERIALFLAG_RTS) {
+ status &= ~TIOCM_RTS;
+
+ switch (settings->tio_serial_attrs_flags & TIO_RTSMASK) {
+ case TIO_RTSENB | TIO_RTSHAND:
+ case TIO_RTSENB | TIO_RTSNOHAND:
+ status |= TIOCM_RTS;
+ break;
+ }
+ }
+
+ if (ioctl(fd, TIOCMSET, &status) < 0)
+ return (tio_error_unknown);
+ }
/* We're good! */
@@ -337,8 +396,8 @@ TIO_HOOK(void) unix_close(cookie_t *cookie)
{
/* Close the file descriptors if necessary. */
- if (cookie->_fd >= 0 && cookie->_cl)
- close(cookie->_fd);
+ if (cookie->fd >= 0 && cookie->cl)
+ close(cookie->fd);
/* Free the cookie and exit. */
@@ -362,7 +421,7 @@ TIO_LOCAL_DATA(tio_serial_functions_t const) unix_serial_functions = {
(tio_read_t *)unix_read,
(tio_write_t *)unix_write,
- (tio_setattrs_t *)unix_set_attrs,
+ (tio_set_serial_attrs_t *)unix_set_attrs,
NULL,
NULL,
@@ -385,7 +444,7 @@ TIO_EXTERN(int) tio_open_unix_file(tio_stream_t **streamp, int fd, int cl)
/* Check if the device is valid. */
if (fd < 0) {
- err = tio_error_invalid;
+ err = tio_error_arg;
goto fail;
}
@@ -394,7 +453,7 @@ TIO_EXTERN(int) tio_open_unix_file(tio_stream_t **streamp, int fd, int cl)
if (write(fd, NULL, 0) < 0)
mode &= ~TIO_OPENFLAG_WRITE;
if (!(mode & (TIO_OPENFLAG_READ | TIO_OPENFLAG_WRITE))) {
- err = tio_error_invalid;
+ err = tio_error_arg;
goto fail;
}
@@ -405,20 +464,11 @@ TIO_EXTERN(int) tio_open_unix_file(tio_stream_t **streamp, int fd, int cl)
goto fail;
}
- cookie->_fd = fd;
- cookie->_cl = cl;
- cookie->_to = -1;
- cookie->_str = 0;
- cookie->_end = -1;
-
- /* Get the read and write timeouts. */
-
- {
- struct termios term;
-
- if (tcgetattr(rfd, &term))
- cookie->_to = term.c_cc[VTIME] * 100;
- }
+ cookie->fd = fd;
+ cookie->cl = cl;
+ cookie->to = -1;
+ cookie->str = 0;
+ cookie->end = -1;
/* Initialize for real. */
@@ -426,7 +476,7 @@ TIO_EXTERN(int) tio_open_unix_file(tio_stream_t **streamp, int fd, int cl)
/* Final call. */
- return (tio_open(streamp, mode, cookie, &unix_functions, 0));
+ return (tio_open(streamp, NULL, cookie, mode, &unix_functions, 0));
fail:
if (fd >= 0 && cl)
close(fd);
@@ -440,6 +490,7 @@ TIO_EXTERN(int) tio_open_unix_serial(tio_stream_t **streamp,
int fd, int cl)
{
cookie_t *cookie = NULL;
+ tio_serial_attrs_t attrs;
int err;
/* Check if the device is valid. */
@@ -469,11 +520,11 @@ TIO_EXTERN(int) tio_open_unix_serial(tio_stream_t **streamp,
goto fail;
}
- cookie->_fd = fd;
- cookie->_cl = cl;
- cookie->_to = -1;
- cookie->_str = 0;
- cookie->_end = -1;
+ cookie->fd = fd;
+ cookie->cl = cl;
+ cookie->to = -1;
+ cookie->str = 0;
+ cookie->end = -1;
/* Initialize for real. */
@@ -481,9 +532,9 @@ TIO_EXTERN(int) tio_open_unix_serial(tio_stream_t **streamp,
/* Final call. */
- return (tio_open(streamp, TIO_OPENFLAG_SERIAL_READ
+ return (tio_open_serial(streamp, NULL, cookie, TIO_OPENFLAG_SERIAL_READ
| TIO_OPENFLAG_SERIAL_WRITE | TIO_OPENFLAG_SERIAL_SETATTRS,
- cookie, &unix_serial_functions, 0));
+ &unix_serial_functions, &attrs, TIO_SERIALFLAG_ALL));
fail:
if (fd >= 0 && cl)
close(fd);
@@ -516,7 +567,7 @@ TIO_EXTERN(int) tio_open_unix_serial_port(tio_stream_t **streamp,
return (tio_error_unknown);
}
- return (tio_open_unix_serial(streamp, fd));
+ return (tio_open_unix_serial(streamp, fd, 1));
}
#endif