From: git Date: Thu, 19 Feb 2026 17:01:34 +0000 (-0500) Subject: added support for locking the device X-Git-Url: https://git.datadissipation.net/?a=commitdiff_plain;h=f7c96360c7e0e78239ed2c4cdf44fa4d783134ac;p=ust.git added support for locking the device --- diff --git a/config.def.h b/config.def.h index 68e1a15..1e68dd1 100644 --- a/config.def.h +++ b/config.def.h @@ -7,8 +7,10 @@ const size_t scratchwsz = 256; const size_t scratchrsz = 256; /* `nanosleep()` values inside the read and write loops */ -const long swritedelay = 0; -const long nswritedelay = 1000000; +const long swritedelay = 0; /* seconds */ +const long nswritedelay = 1000000; /* nanoseconds */ + +/* other names follow the same logic as above */ const long sreaddelay = 0; const long nsreaddelay = 1000000; @@ -17,6 +19,9 @@ const long nsreaddelay = 1000000; const long spulsedelay = 0; const long nspulsedelay = 1000000; +/* lock the opened device */ +const int exclusive = 1; /*(0|1)*/ + /* escape character for interactive use */ const char escapechar = '~'; @@ -45,6 +50,7 @@ int verbose = 0; /*(0|1)*/ * NetBSD: * dty* - opening does not block, does not wait for DCD * tty* - 'dial-in' device, blocks opening until a connection is established + * ttyU* - USB variant */ char line[16] = "/dev/cuau0"; @@ -77,25 +83,24 @@ int canonical = 0; /*(0|1)*/ /* * CR and LF (NL) translation options */ - -typedef struct{ - int crinlf; - int crtolf; - int lfincr; - int lftocr; - int nocr; - int nolf; -} CRLFOpt; - -CRLFOpt tropts = {0}; -CRLFOpt itropts = {0}; +CRLFOpt tropts = { 0 }; +CRLFOpt itropts = { 0 }; /* * backspace: setting to one makes `^H` the backspace character, `^?` otherwise */ int backspace = 0; /*(0|1)*/ -int minchars = 1; +/* + * the minimum of characters input before sending them to the line + */ +int minchars = 1; /*(>=1)*/ + +/* + * delay between single characters being sent if the buffer has + * more than 1 (redirected stdin, writing a file) + * in nanoseconds + */ long chardelay = 0; /* diff --git a/ust.c b/ust.c index 9e507c8..4517e0c 100644 --- a/ust.c +++ b/ust.c @@ -1,6 +1,7 @@ +#include + #include #include -#include #include #include #include @@ -8,8 +9,9 @@ #include #include #include + +#include #include -#include #ifdef __linux__ #include @@ -18,8 +20,6 @@ #include #endif -#include "config.h" - #define CR '\r' #define LF '\n' #define BS '\b' @@ -42,6 +42,18 @@ typedef struct { ssize_t sizesm; } Sizes; +typedef struct{ + int crinlf; + int crtolf; + int lfincr; + int lftocr; + int nocr; + int nolf; +} CRLFOpt; + +/* including here to access CRLFOpt */ +#include "config.h" + static int gettermattr(int dv, void *strct); static int settermattr(int dv, const void *strct); static void settermspd(unsigned int lispeed, unsigned int lospeed, const void *strct); @@ -63,9 +75,9 @@ static void sighandl(int signo); static void die(int code, const char *msg, ...); #ifdef __linux__ - static struct termios2 cntrl, origterm = {0}, newterm = {0}; + static struct termios2 cntrl, origterm = { 0 }, newterm = { 0 }; #else - static struct termios cntrl, origterm = {0}, newterm = {0}; + static struct termios cntrl, origterm = { 0 }, newterm = { 0 }; #endif static Args bsargs = {DEL, DEL, 0}; @@ -126,9 +138,12 @@ settermspd(unsigned int lispeed, unsigned int lospeed, const void *strct) int openport() { + int flags; + struct flock fl = { 0 }; + if (verbose) fprintf(stderr, "opening \"%s\"\n", line); - fd = open(line, O_RDWR | O_NOCTTY | O_NDELAY); + fd = open(line, (O_RDWR | O_NOCTTY | O_NDELAY)); if (fd == -1) { perror("error opening device"); exit(1); @@ -139,18 +154,32 @@ openport() if (!isatty(fd)) die(2, "device \"%s\" is not a TTY\n", line); - int flags; flags = fcntl(fd, F_GETFL, 0); /* opened to check with non-blocking mode, now set to blocking */ flags &= ~(O_NONBLOCK | O_NDELAY); - if (fcntl(fd, F_SETFL, flags) == -1) - die(1, "failed to set the device to blocking mode\n"); + + if (fcntl(fd, F_SETFL, flags) == -1) { + perror("fcntl"); + die(1, "exiting now\n"); + } if (gettermattr(fd, &cntrl) == -1) die(1, "failed to get device attributes\n"); - + + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + + if (exclusive) { + if (fcntl(fd, F_SETLK, &fl) == -1) { + perror("fcntl"); + die(1, "failed to lock the device, exiting now\n"); + } + } + if (verbose) fprintf(stderr, "setting baudrate [RX:%u | TX:%u]\n", ispeed, ospeed); - + settermspd(ispeed, ospeed, &cntrl); if (settermattr(fd, &cntrl) == -1) die(2,"failed to set baudrate [RX:%u | TX:%u]\n", ispeed, ospeed); @@ -165,10 +194,10 @@ openport() cntrl.c_cflag |= PARENB; if (parity == 2) cntrl.c_cflag |= PARENB | PARODD; - + if (settermattr(fd, &cntrl) == -1) die(2, "failed to set parity [even: %d, odd: %d]\n", parity & 1, (parity & 2) >> 1); - + if (verbose) { /* it's so ugly and beautiful at the same time */ int t = (((hard & 1) << 1) & (hard & 2)) >> 1; @@ -236,6 +265,9 @@ openport() if (settermattr(fd, &cntrl) == -1) die(1, "failed to set stop bits [%d]\n", stopb+1); + cntrl.c_cc[VMIN] = 1; + cntrl.c_cc[VTIME] = 0; + #ifdef __linux__ ioctl(fd, TCFLSH, TCIOFLUSH); #else @@ -251,7 +283,7 @@ strtoui(const char *str, const char *msg, unsigned int min) char *endptr; t = strtol(str, &endptr, 10); - if (errno != 0 || *endptr != '\0' || t < min) { + if (errno != 0 || *endptr != '\0' || t < min || t > uintmax) { fprintf(stderr, msg, str); return uintmax; } @@ -344,6 +376,7 @@ writeport(void *unused) { Sizes msizes; struct timespec ts; + ts.tv_sec = swritedelay; ts.tv_nsec = nswritedelay; wts.tv_sec = 0; @@ -526,9 +559,14 @@ interchck() newterm.c_iflag |= INLCR; newterm.c_cc[VMIN] = minchars; - newterm.c_cc[VINTR] = _POSIX_VDISABLE; - newterm.c_cc[VSUSP] = _POSIX_VDISABLE; - newterm.c_cc[VQUIT] = _POSIX_VDISABLE; + newterm.c_cc[VTIME] = 0; + newterm.c_cc[VINTR] = newterm.c_cc[VSUSP]\ + = newterm.c_cc[VQUIT] = newterm.c_cc[VLNEXT]\ + = newterm.c_cc[VDISCARD] = _POSIX_VDISABLE; + + #ifdef VDSUSP + newterm.c_cc[VDSUSP] = _POSIX_VDISABLE; + #endif if (backspace) bsargs.input = BS; @@ -536,7 +574,7 @@ interchck() bsargs.input = DEL; bsargs.find = origterm.c_cc[VERASE]; - + if (settermattr(STDOUT_FILENO, &newterm) < 0) die(1, "failed to set terminal attributes\n"); } @@ -559,13 +597,13 @@ void getcmd(int escape) { Sizes msizes; - msizes.sizesm = scratchwsz; - msizes.sizebm = wbuffsz; - char cmdchar; char ttr[64]; unsigned int tspd; + msizes.sizesm = scratchwsz; + msizes.sizebm = wbuffsz; + if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) interactive = 1; @@ -910,6 +948,7 @@ main(int argc, char **argv) signal(SIGINT, sighandl); signal(SIGQUIT, sighandl); signal(SIGTERM, sighandl); + signal(SIGCHLD, SIG_DFL); fd = openport();