diff options
author | Thomas Touhey <thomas@touhey.fr> | 2019-04-29 14:34:38 +0200 |
---|---|---|
committer | Thomas Touhey <thomas@touhey.fr> | 2019-04-29 14:34:38 +0200 |
commit | 06339feadeda7f0237cf3919d68d61439e5c15c2 (patch) | |
tree | fa4757026c86c9c21b60d44f0836a1c88cd8540b /lib/stream/builtin/unix.c | |
parent | 751f742fc8b8be0746b54d45822b9351f8079a64 (diff) |
Fixed POSIX building
Diffstat (limited to 'lib/stream/builtin/unix.c')
-rw-r--r-- | lib/stream/builtin/unix.c | 271 |
1 files changed, 161 insertions, 110 deletions
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 |